iqm-station-control-client 9.10.0__tar.gz → 9.12.0__tar.gz
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.
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/CHANGELOG.rst +21 -0
- {iqm_station_control_client-9.10.0/src/iqm_station_control_client.egg-info → iqm_station_control_client-9.12.0}/PKG-INFO +1 -1
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/qon.py +223 -86
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/jobs.py +1 -1
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0/src/iqm_station_control_client.egg-info}/PKG-INFO +1 -1
- iqm_station_control_client-9.12.0/version.txt +1 -0
- iqm_station_control_client-9.10.0/version.txt +0 -1
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/LICENSE.txt +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/MANIFEST.in +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/README.rst +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/API.rst +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/Makefile +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/_static/css/custom.css +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/_static/images/favicon.ico +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/_static/images/logo.png +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/_templates/autosummary-class-template.rst +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/_templates/autosummary-module-template.rst +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/changelog.rst +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/conf.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/index.rst +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/license.rst +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/pyproject.toml +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/requirements/base.in +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/requirements/base.txt +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/setup.cfg +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/setup.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/__init__.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/__init__.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/error.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/grpc_utils.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/iqm_server_client.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/__init__.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/calibration_pb2.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/calibration_pb2.pyi +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/calibration_pb2_grpc.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/common_pb2.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/common_pb2.pyi +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/common_pb2_grpc.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/job_pb2.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/job_pb2.pyi +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/job_pb2_grpc.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/qc_pb2.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/qc_pb2.pyi +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/qc_pb2_grpc.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/uuid_pb2.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/uuid_pb2.pyi +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/proto/uuid_pb2_grpc.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/testing/__init__.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/iqm_server/testing/iqm_server_mock.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/list_models.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/py.typed +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/__init__.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/channel_property_serializer.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/datetime_serializers.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/playlist_serializers.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/run_serializers.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/setting_node_serializer.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/struct_serializer.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/sweep_serializers.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/serializers/task_serializers.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/station_control.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/client/utils.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/__init__.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/list_with_meta.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/__init__.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/dut.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/dynamic_quantum_architecture.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/monitor.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/observation.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/observation_set.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/run.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/sequence.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/static_quantum_architecture.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/sweep.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/models/type_aliases.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/py.typed +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/pydantic_base.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm/station_control/interface/station_control.py +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm_station_control_client.egg-info/SOURCES.txt +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm_station_control_client.egg-info/dependency_links.txt +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm_station_control_client.egg-info/requires.txt +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/src/iqm_station_control_client.egg-info/top_level.txt +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/tests/.pylintrc +0 -0
- {iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/tests/__init__.py +0 -0
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version 9.12.0 (2025-08-08)
|
|
6
|
+
===========================
|
|
7
|
+
|
|
8
|
+
Features
|
|
9
|
+
--------
|
|
10
|
+
|
|
11
|
+
- QON subclasses are now pydantic dataclasses.
|
|
12
|
+
- Modifies typing of QON subclasses to validate some of the inputs using regex.
|
|
13
|
+
- Add ``QONMetricRegistry`` to register parsing of QON metric subclasses for different methods.
|
|
14
|
+
- Refactor ``QONMetric`` into a base class, with new subclasses ``QONGateMetric`` and ``QONSystemMetric`` to handle gate-related and gate-unrelated metric generation.
|
|
15
|
+
- Add more strict regex validation on QON subclasses.
|
|
16
|
+
- Update tests to reflect the new structure and validation rules.
|
|
17
|
+
|
|
18
|
+
Version 9.11.0 (2025-08-07)
|
|
19
|
+
===========================
|
|
20
|
+
|
|
21
|
+
Features
|
|
22
|
+
--------
|
|
23
|
+
|
|
24
|
+
- Fix naming conventions related to Pulse level access as ``Pulla``.
|
|
25
|
+
|
|
5
26
|
Version 9.10.0 (2025-08-07)
|
|
6
27
|
===========================
|
|
7
28
|
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
18
|
from collections.abc import Iterable
|
|
19
|
-
from dataclasses import dataclass, field
|
|
20
19
|
from enum import StrEnum
|
|
21
20
|
import logging
|
|
22
|
-
from typing import Any, Final, TypeAlias
|
|
21
|
+
from typing import Annotated, Any, Final, TypeAlias
|
|
22
|
+
|
|
23
|
+
from pydantic import Field
|
|
24
|
+
from pydantic.dataclasses import dataclass
|
|
23
25
|
|
|
24
26
|
from iqm.station_control.interface.models.observation import ObservationBase
|
|
25
27
|
|
|
@@ -35,6 +37,9 @@ _SUFFIX_SEPARATOR: Final[str] = ":"
|
|
|
35
37
|
LOCUS_SEPARATOR: Final[str] = "__"
|
|
36
38
|
"""Separates QPU components in a locus string."""
|
|
37
39
|
|
|
40
|
+
_PATTERN: Final[str] = r"^[A-Za-z_][A-Za-z0-9_]*$"
|
|
41
|
+
"""Regex that most observation name parts must follow."""
|
|
42
|
+
|
|
38
43
|
Locus: TypeAlias = tuple[str, ...]
|
|
39
44
|
"""Sequence of QPU component physical names a quantum operation acts on. The order may matter."""
|
|
40
45
|
|
|
@@ -77,7 +82,7 @@ def _parse_suffixes(suffixes: Iterable[str]) -> Suffixes:
|
|
|
77
82
|
return dict(sorted(suffix_dict.items()))
|
|
78
83
|
|
|
79
84
|
|
|
80
|
-
@dataclass(frozen=True)
|
|
85
|
+
@dataclass(frozen=True, config={"extra": "forbid"}) # do not allow unknown keyword args
|
|
81
86
|
class QON:
|
|
82
87
|
"""Qualified observation name.
|
|
83
88
|
|
|
@@ -103,7 +108,7 @@ class QON:
|
|
|
103
108
|
raise NotImplementedError
|
|
104
109
|
|
|
105
110
|
@classmethod
|
|
106
|
-
def from_str(cls, name: str) ->
|
|
111
|
+
def from_str(cls, name: str) -> QON:
|
|
107
112
|
"""Parse an observation name into a QON object.
|
|
108
113
|
|
|
109
114
|
Args:
|
|
@@ -162,7 +167,7 @@ class QONCharacterization(QON):
|
|
|
162
167
|
return _FIELD_SEPARATOR.join([self.domain, "model", self.component, self.quantity])
|
|
163
168
|
|
|
164
169
|
@classmethod
|
|
165
|
-
def _parse(cls, rest: str) ->
|
|
170
|
+
def _parse(cls, rest: str) -> QONCharacterization:
|
|
166
171
|
"""Parse a characterization observation name."""
|
|
167
172
|
parts = rest.split(_FIELD_SEPARATOR, maxsplit=1)
|
|
168
173
|
if len(parts) < 2:
|
|
@@ -175,8 +180,131 @@ class QONCharacterization(QON):
|
|
|
175
180
|
)
|
|
176
181
|
|
|
177
182
|
|
|
183
|
+
class QONMetricRegistry:
|
|
184
|
+
"""Registry for QONMetric subclasses, mapping method names to parser classes.
|
|
185
|
+
|
|
186
|
+
Allows extensible registration of new metric parsing strategies for new methods.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
_registry: dict[str, type[QONMetric]] = {}
|
|
190
|
+
"""Mapping from QONMetric method name to the subclass that handles it."""
|
|
191
|
+
_inv_registry: dict[type[QONMetric], frozenset[str]] = {}
|
|
192
|
+
"""Mapping from QONMetric subclass to the methods it handles."""
|
|
193
|
+
|
|
194
|
+
@classmethod
|
|
195
|
+
def register(cls, method_names: Iterable[str]):
|
|
196
|
+
"""Decorator for registering a QONMetric subclass as the parser for one or more method names.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
method_names: One or more method names to associate with the subclass.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
The decorator function.
|
|
203
|
+
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
def decorator(subclass: type[QONMetric]):
|
|
207
|
+
for name in method_names:
|
|
208
|
+
if (owner := cls._registry.get(name)) is not None:
|
|
209
|
+
raise ValueError(f"Method {name} already registered to {owner.__name__}")
|
|
210
|
+
cls._registry[name] = subclass
|
|
211
|
+
cls._inv_registry[subclass] = frozenset(method_names)
|
|
212
|
+
return subclass
|
|
213
|
+
|
|
214
|
+
return decorator
|
|
215
|
+
|
|
216
|
+
@classmethod
|
|
217
|
+
def get_parser(cls, method_name: str) -> type[QONMetric]:
|
|
218
|
+
"""Retrieve the parser class for a given method name.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
method_name: The method name to look up.
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
The QONMetric subclass registered for the method.
|
|
225
|
+
|
|
226
|
+
Raises:
|
|
227
|
+
UnknownObservationError: ``method_name`` is not registered.
|
|
228
|
+
|
|
229
|
+
"""
|
|
230
|
+
try:
|
|
231
|
+
return cls._registry[method_name]
|
|
232
|
+
except KeyError:
|
|
233
|
+
raise UnknownObservationError("Unknown quality metric.")
|
|
234
|
+
|
|
235
|
+
@classmethod
|
|
236
|
+
def registered_methods(cls) -> list[str]:
|
|
237
|
+
"""Get a list of all registered method names.
|
|
238
|
+
|
|
239
|
+
Returns:
|
|
240
|
+
List of registered method names.
|
|
241
|
+
|
|
242
|
+
"""
|
|
243
|
+
return list(cls._registry.keys())
|
|
244
|
+
|
|
245
|
+
|
|
178
246
|
@dataclass(frozen=True)
|
|
179
247
|
class QONMetric(QON):
|
|
248
|
+
"""Base class for QON representing a gate quality metric.
|
|
249
|
+
|
|
250
|
+
Subclasses implement parsing and string representation for specific methods.
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
method: Annotated[str, Field(pattern=_PATTERN)]
|
|
254
|
+
locus: str
|
|
255
|
+
"""Sequence of names of QPU components on which the gate is applied, or on which the experiment is run."""
|
|
256
|
+
metric: Annotated[str, Field(pattern=r"^[A-Za-z_0-9][A-Za-z0-9_]*$")]
|
|
257
|
+
"""Measured metric."""
|
|
258
|
+
|
|
259
|
+
def __post_init__(self):
|
|
260
|
+
if self.method not in QONMetricRegistry._inv_registry[self.__class__]:
|
|
261
|
+
raise UnknownObservationError(
|
|
262
|
+
f"{self.__class__.__name__} is not registered to handle the method {self.method}"
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
@property
|
|
266
|
+
def domain(self) -> Domain:
|
|
267
|
+
"""Return the QON domain for metrics."""
|
|
268
|
+
return Domain.METRIC
|
|
269
|
+
|
|
270
|
+
@classmethod
|
|
271
|
+
def _parse(cls, method: str, method_specific_part: str) -> QONMetric:
|
|
272
|
+
"""Parse a metric observation name using the appropriate registered subclass.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
method: The method name.
|
|
276
|
+
method_specific_part: The method-specific part of the metric observation name.
|
|
277
|
+
|
|
278
|
+
Returns:
|
|
279
|
+
Parsed metric name.
|
|
280
|
+
|
|
281
|
+
Raises:
|
|
282
|
+
UnknownObservationError: ``method`` is not registered.
|
|
283
|
+
|
|
284
|
+
"""
|
|
285
|
+
parser_cls = QONMetricRegistry.get_parser(method)
|
|
286
|
+
return parser_cls._parse(method, method_specific_part)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
@QONMetricRegistry.register(
|
|
290
|
+
[
|
|
291
|
+
"rb",
|
|
292
|
+
"irb",
|
|
293
|
+
"ssro",
|
|
294
|
+
"restless_ssro",
|
|
295
|
+
"readout_rb",
|
|
296
|
+
"qndness",
|
|
297
|
+
"msmt_qndness",
|
|
298
|
+
"npopex_echo",
|
|
299
|
+
"npopex_long",
|
|
300
|
+
"coherence_cz",
|
|
301
|
+
"ncz_swap",
|
|
302
|
+
"entanglement_coherence",
|
|
303
|
+
"conditional_reset",
|
|
304
|
+
]
|
|
305
|
+
)
|
|
306
|
+
@dataclass(frozen=True)
|
|
307
|
+
class QONGateMetric(QONMetric):
|
|
180
308
|
"""QON representing a gate quality metric.
|
|
181
309
|
|
|
182
310
|
Has the form ``metrics.{method}.{method_specific_part}``.
|
|
@@ -209,97 +337,107 @@ class QONMetric(QON):
|
|
|
209
337
|
locus: QB4
|
|
210
338
|
metric: fidelity
|
|
211
339
|
suffixes: {"par": "d2"}
|
|
212
|
-
|
|
213
|
-
``metrics.ghz_state.QB1__QB2.coherence_lower_bound``
|
|
214
|
-
|
|
215
|
-
method: ghz_state
|
|
216
|
-
gate: None
|
|
217
|
-
implementation: None
|
|
218
|
-
locus: QB1__QB2
|
|
219
|
-
metric: coherence_lower_bound
|
|
220
|
-
suffixes: {}
|
|
221
|
-
|
|
222
340
|
"""
|
|
223
341
|
|
|
224
|
-
|
|
225
|
-
gate: str | None
|
|
342
|
+
gate: Annotated[str, Field(pattern=_PATTERN)]
|
|
226
343
|
"""Name of the gate/quantum operation."""
|
|
227
|
-
implementation: str
|
|
344
|
+
implementation: Annotated[str, Field(pattern=_PATTERN)]
|
|
228
345
|
"""Name of the gate implementation."""
|
|
229
|
-
|
|
230
|
-
"""Sequence of names of QPU components on which the gate/operation is applied."""
|
|
231
|
-
metric: str
|
|
232
|
-
"""Measured metric."""
|
|
233
|
-
suffixes: Suffixes = field(default_factory=dict)
|
|
346
|
+
suffixes: Suffixes = Field(default_factory=dict)
|
|
234
347
|
"""Suffixes defining the metric further (if any)."""
|
|
235
348
|
|
|
236
|
-
@property
|
|
237
|
-
def domain(self) -> Domain:
|
|
238
|
-
return Domain.METRIC
|
|
239
|
-
|
|
240
349
|
def __str__(self) -> str:
|
|
241
|
-
|
|
242
|
-
parts = [self.domain, self.method, self.locus, self.metric]
|
|
243
|
-
else:
|
|
244
|
-
gate_str = self.gate if self.gate is not None else ""
|
|
245
|
-
impl_str = self.implementation if self.implementation is not None else ""
|
|
246
|
-
parts = [self.domain, self.method, gate_str, impl_str, self.locus, self.metric]
|
|
350
|
+
parts = [self.domain, self.method, self.gate, self.implementation, self.locus, self.metric]
|
|
247
351
|
name = _FIELD_SEPARATOR.join(parts)
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
return f"{name}:{
|
|
352
|
+
if self.suffixes:
|
|
353
|
+
suffix_str = _SUFFIX_SEPARATOR.join(f"{k}={v}" for k, v in sorted(self.suffixes.items()))
|
|
354
|
+
return f"{name}:{suffix_str}"
|
|
251
355
|
return name
|
|
252
356
|
|
|
253
357
|
@classmethod
|
|
254
|
-
def _parse(cls, method: str, method_specific_part: str) ->
|
|
255
|
-
"""Parse a gate
|
|
358
|
+
def _parse(cls, method: str, method_specific_part: str) -> QONGateMetric:
|
|
359
|
+
"""Parse a metric observation name that includes a gate and an implementation.
|
|
256
360
|
|
|
257
361
|
Args:
|
|
258
|
-
method:
|
|
259
|
-
method_specific_part:
|
|
362
|
+
method: The method name.
|
|
363
|
+
method_specific_part: The method-specific part of the metric observation name.
|
|
364
|
+
|
|
365
|
+
Returns:
|
|
366
|
+
Parsed metric name.
|
|
260
367
|
|
|
261
368
|
Raises:
|
|
262
|
-
ValueError:
|
|
263
|
-
UnknownObservationError: Failed to parse ``name`` because it contains unknown elements.
|
|
369
|
+
ValueError: Observation name is malformed.
|
|
264
370
|
|
|
265
371
|
"""
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
return cls(
|
|
279
|
-
method=method,
|
|
280
|
-
gate=gate,
|
|
281
|
-
implementation=implementation,
|
|
282
|
-
locus=locus,
|
|
283
|
-
metric=metric,
|
|
284
|
-
suffixes=suffixes,
|
|
285
|
-
)
|
|
372
|
+
parts, suffixes = _split_obs_name(method_specific_part, maxsplit=3)
|
|
373
|
+
if len(parts) < 4:
|
|
374
|
+
raise ValueError(f"{method} gate quality metric name has less than 6 parts")
|
|
375
|
+
gate, implementation, locus, metric = parts
|
|
376
|
+
return cls(
|
|
377
|
+
method=method,
|
|
378
|
+
gate=gate,
|
|
379
|
+
implementation=implementation,
|
|
380
|
+
locus=locus,
|
|
381
|
+
metric=metric,
|
|
382
|
+
suffixes=suffixes,
|
|
383
|
+
)
|
|
286
384
|
|
|
287
|
-
if method == "ghz_state":
|
|
288
|
-
# {locus_str}.{metric}
|
|
289
|
-
parts = fields.split(_FIELD_SEPARATOR, maxsplit=1)
|
|
290
|
-
if len(parts) < 2:
|
|
291
|
-
raise ValueError(f"{method} gate quality metric name has less than 4 parts")
|
|
292
|
-
locus, metric = parts
|
|
293
|
-
return cls(
|
|
294
|
-
method=method,
|
|
295
|
-
gate=None,
|
|
296
|
-
implementation=None,
|
|
297
|
-
locus=locus,
|
|
298
|
-
metric=metric,
|
|
299
|
-
suffixes=suffixes,
|
|
300
|
-
)
|
|
301
385
|
|
|
302
|
-
|
|
386
|
+
@QONMetricRegistry.register(["ghz_state", "coherence_gef", "relaxation_ef", "simultaneous_coherence_gef", "t1_coupled"])
|
|
387
|
+
@dataclass(frozen=True)
|
|
388
|
+
class QONSystemMetric(QONMetric):
|
|
389
|
+
"""QON representing a system quality metric.
|
|
390
|
+
|
|
391
|
+
Has the form ``metrics.{method}.{locus}.{metric}``.
|
|
392
|
+
|
|
393
|
+
Can parse/represent e.g. the following metrics:
|
|
394
|
+
|
|
395
|
+
``metrics.irb.circuit.random_circuit.QB4.fidelity:par=d2``
|
|
396
|
+
|
|
397
|
+
method: irb
|
|
398
|
+
gate: circuit
|
|
399
|
+
implementation: random_circuit
|
|
400
|
+
locus: QB4
|
|
401
|
+
metric: fidelity
|
|
402
|
+
suffixes: {"par": "d2"}
|
|
403
|
+
|
|
404
|
+
``metrics.ghz_state.QB1__QB2.coherence_lower_bound``
|
|
405
|
+
|
|
406
|
+
method: ghz_state
|
|
407
|
+
locus: QB1__QB2
|
|
408
|
+
metric: coherence_lower_bound
|
|
409
|
+
|
|
410
|
+
Subclasses implement parsing and string representation for specific methods.
|
|
411
|
+
"""
|
|
412
|
+
|
|
413
|
+
def __str__(self) -> str:
|
|
414
|
+
parts = [self.domain, self.method, self.locus, self.metric]
|
|
415
|
+
return _FIELD_SEPARATOR.join(parts)
|
|
416
|
+
|
|
417
|
+
@classmethod
|
|
418
|
+
def _parse(cls, method: str, method_specific_part: str) -> QONSystemMetric:
|
|
419
|
+
"""Parse a metric observation name without a gate or an implementation.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
method: The method name.
|
|
423
|
+
method_specific_part: The method-specific part of the metric observation name.
|
|
424
|
+
|
|
425
|
+
Returns:
|
|
426
|
+
Parsed metric name.
|
|
427
|
+
|
|
428
|
+
Raises:
|
|
429
|
+
ValueError: Observation name is malformed.
|
|
430
|
+
|
|
431
|
+
"""
|
|
432
|
+
parts = method_specific_part.split(_FIELD_SEPARATOR, maxsplit=1)
|
|
433
|
+
if len(parts) < 2:
|
|
434
|
+
raise ValueError(f"{method} system quality metric name has less than 4 parts")
|
|
435
|
+
locus, metric = parts
|
|
436
|
+
return cls(
|
|
437
|
+
method=method,
|
|
438
|
+
locus=locus,
|
|
439
|
+
metric=metric,
|
|
440
|
+
)
|
|
303
441
|
|
|
304
442
|
|
|
305
443
|
@dataclass(frozen=True)
|
|
@@ -309,7 +447,7 @@ class QONControllerSetting(QON):
|
|
|
309
447
|
Has the form ``controllers.{controller}[.{subcontroller}]*.{setting}``.
|
|
310
448
|
"""
|
|
311
449
|
|
|
312
|
-
controller: str
|
|
450
|
+
controller: Annotated[str, Field(pattern=_PATTERN)]
|
|
313
451
|
"""Name of the controller."""
|
|
314
452
|
rest: str
|
|
315
453
|
"""Possible subcontroller names in a dotted structure, ending in the setting name."""
|
|
@@ -322,7 +460,7 @@ class QONControllerSetting(QON):
|
|
|
322
460
|
return _FIELD_SEPARATOR.join([self.domain, self.controller, self.rest])
|
|
323
461
|
|
|
324
462
|
@classmethod
|
|
325
|
-
def _parse(cls, controller: str, controller_specific_part: str) ->
|
|
463
|
+
def _parse(cls, controller: str, controller_specific_part: str) -> QONControllerSetting:
|
|
326
464
|
"""Parse a controller setting observation name."""
|
|
327
465
|
return cls(
|
|
328
466
|
controller=controller,
|
|
@@ -337,9 +475,9 @@ class QONGateParam(QON):
|
|
|
337
475
|
Has the form ``gates.{gate}.{implementation}.{locus_str}.{parameter}``.
|
|
338
476
|
"""
|
|
339
477
|
|
|
340
|
-
gate: str
|
|
478
|
+
gate: Annotated[str, Field(pattern=_PATTERN)]
|
|
341
479
|
"""Name of the gate/quantum operation."""
|
|
342
|
-
implementation: str
|
|
480
|
+
implementation: Annotated[str, Field(pattern=_PATTERN)]
|
|
343
481
|
"""Name of the gate implementation."""
|
|
344
482
|
locus: str
|
|
345
483
|
"""Sequence of names of QPU components on which the gate is applied."""
|
|
@@ -351,11 +489,10 @@ class QONGateParam(QON):
|
|
|
351
489
|
return Domain.GATE_PARAMETER
|
|
352
490
|
|
|
353
491
|
def __str__(self) -> str:
|
|
354
|
-
|
|
355
|
-
return _FIELD_SEPARATOR.join([self.domain, self.gate, impl_str, self.locus, self.parameter])
|
|
492
|
+
return _FIELD_SEPARATOR.join([self.domain, self.gate, self.implementation, self.locus, self.parameter])
|
|
356
493
|
|
|
357
494
|
@classmethod
|
|
358
|
-
def _parse(cls, gate: str, rest: str) ->
|
|
495
|
+
def _parse(cls, gate: str, rest: str) -> QONGateParam:
|
|
359
496
|
"""Parse a gate parameter observation name."""
|
|
360
497
|
parts = rest.split(_FIELD_SEPARATOR, maxsplit=2)
|
|
361
498
|
if len(parts) < 3:
|
|
@@ -369,14 +506,14 @@ class QONGateParam(QON):
|
|
|
369
506
|
)
|
|
370
507
|
|
|
371
508
|
|
|
372
|
-
def _split_obs_name(obs_name: str) -> tuple[list[str], Suffixes]:
|
|
509
|
+
def _split_obs_name(obs_name: str, *, maxsplit: int = -1) -> tuple[list[str], Suffixes]:
|
|
373
510
|
"""Split the given observation name into path elements and suffixes."""
|
|
374
511
|
# some observation names may have suffixes, split them off
|
|
375
512
|
fragments = obs_name.split(_SUFFIX_SEPARATOR)
|
|
376
513
|
suffixes = _parse_suffixes(fragments[1:])
|
|
377
514
|
|
|
378
515
|
# split the path elements
|
|
379
|
-
path = fragments[0].split(_FIELD_SEPARATOR)
|
|
516
|
+
path = fragments[0].split(_FIELD_SEPARATOR, maxsplit=maxsplit)
|
|
380
517
|
return path, suffixes
|
|
381
518
|
|
|
382
519
|
|
|
@@ -81,7 +81,7 @@ class JobExecutorStatus(Enum):
|
|
|
81
81
|
VALIDATION_ENDED = "validation_ended"
|
|
82
82
|
"""The job passed validation."""
|
|
83
83
|
|
|
84
|
-
# Running
|
|
84
|
+
# Running Pulla
|
|
85
85
|
FETCH_CALIBRATION_STARTED = "fetch_calibration_started"
|
|
86
86
|
"""Calibration data for the job is being fetched."""
|
|
87
87
|
FETCH_CALIBRATION_ENDED = "fetch_calibration_ended"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
9.12.0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
9.10.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/_static/css/custom.css
RENAMED
|
File without changes
|
|
File without changes
|
{iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/docs/_static/images/logo.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/requirements/base.in
RENAMED
|
File without changes
|
{iqm_station_control_client-9.10.0 → iqm_station_control_client-9.12.0}/requirements/base.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|