boulder-opal-scale-up-sdk 1.0.5__tar.gz → 1.0.7__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.
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/PKG-INFO +2 -2
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/agent/worker.py +15 -2
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/common/dtypes.py +48 -4
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/constants.py +15 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/controller/qblox.py +10 -2
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/controller/quantum_machines.py +86 -17
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/processor/common.py +3 -3
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/errors.py +21 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/__init__.py +8 -2
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/experiments/cz_spectroscopy_by_bias.py +84 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/power_rabi.py +1 -1
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/power_rabi_ef.py +1 -1
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/experiments/ramsey_ef.py +62 -0
- boulder_opal_scale_up_sdk-1.0.5/boulderopalscaleupsdk/experiments/readout_classifier_calibration.py → boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/experiments/readout_classifier.py +7 -3
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/experiments/readout_optimization.py +57 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/resonator_spectroscopy_by_bias.py +2 -4
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/t2.py +1 -1
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/transmon_anharmonicity.py +0 -2
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/waveforms.py +15 -0
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/grpc_interceptors/error.py +318 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/plotting/dtypes.py +5 -5
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/protobuf/v1/device_pb2.py +97 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/protobuf/v1/device_pb2.pyi +76 -46
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/protobuf/v1/device_pb2_grpc.py +100 -66
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/protobuf/v1/job_pb2.py +47 -0
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/protobuf/v1/job_pb2.pyi +54 -0
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/protobuf/v1/job_pb2_grpc.py +138 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/routines/__init__.py +2 -0
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/routines/coupler_discovery.py +37 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/routines/transmon_retuning.py +0 -4
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/solutions/__init__.py +22 -0
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/solutions/common.py +23 -0
- boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/solutions/placeholder_solution.py +28 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/third_party/quantum_machines/__init__.py +16 -1
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/third_party/quantum_machines/config.py +50 -50
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/pyproject.toml +2 -2
- boulder_opal_scale_up_sdk-1.0.5/boulderopalscaleupsdk/protobuf/v1/device_pb2.py +0 -89
- boulder_opal_scale_up_sdk-1.0.5/boulderopalscaleupsdk/stubs/dtypes.py +0 -47
- boulder_opal_scale_up_sdk-1.0.5/boulderopalscaleupsdk/stubs/maps.py +0 -18
- boulder_opal_scale_up_sdk-1.0.5/boulderopalscaleupsdk/utils/__init__.py +0 -12
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/LICENSE +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/README.md +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/agent/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/common/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/common/typeclasses.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/common.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/config_loader.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/controller/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/controller/base.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/controller/resolver.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/defcal.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/device.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/processor/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/device/processor/superconducting_processor.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/chi01_scan.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/common.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/drag_leakage_calibration.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/fine_amplitude_calibration.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/ramsey.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/resonator_spectroscopy.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/resonator_spectroscopy_by_power.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/t1.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/t2_echo.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/transmon_spectroscopy.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/voltage_bias_fine_tune.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/experiments/zz_ramsey.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/grpc_interceptors/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/grpc_interceptors/auth.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/plotting/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/protobuf/v1/agent_pb2.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/protobuf/v1/agent_pb2.pyi +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/protobuf/v1/agent_pb2_grpc.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/protobuf/v1/task_pb2.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/protobuf/v1/task_pb2.pyi +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/protobuf/v1/task_pb2_grpc.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/py.typed +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/routines/common.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/routines/one_qubit_calibration.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/routines/resonator_mapping.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/routines/transmon_coherence.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/routines/transmon_discovery.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/third_party/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/third_party/quantum_machines/constants.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5/boulderopalscaleupsdk/stubs → boulder_opal_scale_up_sdk-1.0.7/boulderopalscaleupsdk/utils}/__init__.py +0 -0
- {boulder_opal_scale_up_sdk-1.0.5 → boulder_opal_scale_up_sdk-1.0.7}/boulderopalscaleupsdk/utils/serial_utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: boulder-opal-scale-up-sdk
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.7
|
4
4
|
Summary: Q-CTRL Boulder Opal Scale Up Python SDK
|
5
5
|
License: https://q-ctrl.com/terms
|
6
6
|
Keywords: black opal,boulder opal,fire opal,nisq,open controls,q control,q ctrl,q-control,q-ctrl,qcontrol,qctrl,quantum,quantum algorithms,quantum circuits,quantum coding,quantum coding software,quantum computing,quantum control,quantum control software,quantum control theory,quantum engineering,quantum error correction,quantum firmware,quantum fundamentals,quantum sensing,qubit,qudit
|
@@ -33,7 +33,7 @@ Requires-Dist: pydantic (>=2.10.4,<3.0.0)
|
|
33
33
|
Requires-Dist: pydantic-settings (>=2.7.0,<3.0.0)
|
34
34
|
Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
|
35
35
|
Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
|
36
|
-
Requires-Dist: qm-qua (==1.2.
|
36
|
+
Requires-Dist: qm-qua (==1.2.3) ; extra == "quantum-machines"
|
37
37
|
Project-URL: Facebook, https://www.facebook.com/qctrl
|
38
38
|
Project-URL: GitHub, https://github.com/qctrl
|
39
39
|
Project-URL: Homepage, https://q-ctrl.com
|
@@ -17,6 +17,7 @@ Contains logic for agent worker.
|
|
17
17
|
"""
|
18
18
|
|
19
19
|
import logging
|
20
|
+
import os
|
20
21
|
from abc import abstractmethod
|
21
22
|
from typing import Protocol
|
22
23
|
|
@@ -28,6 +29,10 @@ from grpc import ssl_channel_credentials
|
|
28
29
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
29
30
|
|
30
31
|
from boulderopalscaleupsdk.common.dtypes import GrpcMetadata, JobId
|
32
|
+
from boulderopalscaleupsdk.constants import (
|
33
|
+
DEFAULT_GRPC_MAX_RECEIVE_MESSAGE_LENGTH,
|
34
|
+
DEFAULT_GRPC_MAX_SEND_MESSAGE_LENGTH,
|
35
|
+
)
|
31
36
|
from boulderopalscaleupsdk.protobuf.v1 import agent_pb2, task_pb2, task_pb2_grpc
|
32
37
|
|
33
38
|
LOG = logging.getLogger(__name__)
|
@@ -171,9 +176,17 @@ class Agent:
|
|
171
176
|
Create a gRPC channel.
|
172
177
|
"""
|
173
178
|
host = url.split(":")[0]
|
179
|
+
grpc_max_send_message_length = os.getenv(
|
180
|
+
"GRPC_MAX_SEND_MESSAGE_LENGTH",
|
181
|
+
DEFAULT_GRPC_MAX_SEND_MESSAGE_LENGTH,
|
182
|
+
)
|
183
|
+
grpc_max_receive_message_length = os.getenv(
|
184
|
+
"GRPC_MAX_RECEIVE_MESSAGE_LENGTH",
|
185
|
+
DEFAULT_GRPC_MAX_RECEIVE_MESSAGE_LENGTH,
|
186
|
+
)
|
174
187
|
options = [
|
175
|
-
("grpc.max_send_message_length",
|
176
|
-
("grpc.max_receive_message_length",
|
188
|
+
("grpc.max_send_message_length", grpc_max_send_message_length),
|
189
|
+
("grpc.max_receive_message_length", grpc_max_receive_message_length),
|
177
190
|
]
|
178
191
|
if host in ["localhost", "127.0.0.1", "0.0.0.0", "::"]:
|
179
192
|
channel = grpc.insecure_channel(
|
@@ -14,7 +14,9 @@
|
|
14
14
|
from __future__ import annotations
|
15
15
|
|
16
16
|
import enum
|
17
|
-
from typing import overload
|
17
|
+
from typing import TypeAlias, overload
|
18
|
+
|
19
|
+
import grpc
|
18
20
|
|
19
21
|
__all__ = [
|
20
22
|
"Duration",
|
@@ -31,6 +33,8 @@ from dateutil.parser import isoparse
|
|
31
33
|
from pydantic import BaseModel, BeforeValidator, ConfigDict, Field, PlainSerializer, TypeAdapter
|
32
34
|
from pydantic.dataclasses import dataclass
|
33
35
|
|
36
|
+
from boulderopalscaleupsdk.plotting import Plot
|
37
|
+
|
34
38
|
GrpcMetadata = list[tuple[str, str | bytes]]
|
35
39
|
|
36
40
|
JobId = str
|
@@ -175,6 +179,9 @@ class Duration:
|
|
175
179
|
return bool(self._np_rep == other._np_rep)
|
176
180
|
return False
|
177
181
|
|
182
|
+
def __str__(self):
|
183
|
+
return f"{self.value} {self.unit.value}"
|
184
|
+
|
178
185
|
def convert(self, unit: TimeUnit) -> Duration | InvalidDurationConversion:
|
179
186
|
val: np.float64 = self._np_rep / np.timedelta64(1, unit)
|
180
187
|
if val.is_integer():
|
@@ -316,6 +323,14 @@ class JobHistorySortOrder(enum.Enum):
|
|
316
323
|
CREATED_AT_DESC = 1
|
317
324
|
CREATED_AT_ASC = 2
|
318
325
|
|
326
|
+
@staticmethod
|
327
|
+
def from_int(value: int) -> JobHistorySortOrder | None:
|
328
|
+
match value:
|
329
|
+
case 1 | 2:
|
330
|
+
return JobHistorySortOrder(value)
|
331
|
+
case _:
|
332
|
+
return None
|
333
|
+
|
319
334
|
|
320
335
|
class JobSummary(BaseModel):
|
321
336
|
id: str
|
@@ -330,13 +345,17 @@ class JobSummary(BaseModel):
|
|
330
345
|
|
331
346
|
class JobDataEntry(BaseModel):
|
332
347
|
message: str
|
333
|
-
created_at: ISO8601DatetimeUTCLike
|
334
|
-
dt: str
|
335
|
-
elapsed_time: str
|
336
348
|
|
337
349
|
class Config:
|
338
350
|
extra = "allow"
|
339
351
|
|
352
|
+
def get_display_items(self) -> list[str | Plot]:
|
353
|
+
items: list[str | Plot] = [self.message]
|
354
|
+
|
355
|
+
if plots := getattr(self, "plots", []):
|
356
|
+
items.extend(TypeAdapter(Plot).validate_python(plot) for plot in plots)
|
357
|
+
return items
|
358
|
+
|
340
359
|
|
341
360
|
class JobData(BaseModel):
|
342
361
|
id: str
|
@@ -346,7 +365,32 @@ class JobData(BaseModel):
|
|
346
365
|
device_name: str
|
347
366
|
data: list[JobDataEntry]
|
348
367
|
|
368
|
+
def get_display_items(self) -> list[str | Plot]:
|
369
|
+
items: list[str | Plot] = []
|
370
|
+
message = "\n".join(
|
371
|
+
[
|
372
|
+
"JobData summary:",
|
373
|
+
f" - id: {self.id}",
|
374
|
+
f" - name: {self.name}",
|
375
|
+
f" - session_id: {self.session_id}",
|
376
|
+
f" - created_at: {self.created_at.isoformat()}",
|
377
|
+
f" - device_name: {self.device_name}",
|
378
|
+
],
|
379
|
+
)
|
380
|
+
items.append(message)
|
381
|
+
|
382
|
+
for job_data_entry in self.data:
|
383
|
+
items.extend(job_data_entry.get_display_items())
|
384
|
+
return items
|
385
|
+
|
349
386
|
|
350
387
|
DEFAULT_JOB_HISTORY_PAGE = 1
|
351
388
|
DEFAULT_JOB_HISTORY_PAGE_SIZE = 10
|
352
389
|
DEFAULT_JOB_HISTORY_SORT_ORDER = JobHistorySortOrder.CREATED_AT_DESC
|
390
|
+
|
391
|
+
SyncClientInterceptor: TypeAlias = (
|
392
|
+
grpc.UnaryUnaryClientInterceptor
|
393
|
+
| grpc.UnaryStreamClientInterceptor
|
394
|
+
| grpc.StreamUnaryClientInterceptor
|
395
|
+
| grpc.StreamStreamClientInterceptor
|
396
|
+
)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
DEFAULT_GRPC_MAX_RECEIVE_MESSAGE_LENGTH = 1024 * 1024 * 50 # 50MB
|
15
|
+
DEFAULT_GRPC_MAX_SEND_MESSAGE_LENGTH = 1024 * 1024 * 50 # 50MB
|
@@ -54,7 +54,7 @@ from dataclasses import dataclass
|
|
54
54
|
from typing import Annotated, Any, ClassVar, Literal, Self, TypeVar
|
55
55
|
|
56
56
|
import numpy as np
|
57
|
-
from pydantic import BaseModel, BeforeValidator, Field, PlainSerializer, model_validator
|
57
|
+
from pydantic import BaseModel, BeforeValidator, ConfigDict, Field, PlainSerializer, model_validator
|
58
58
|
|
59
59
|
from boulderopalscaleupsdk.device.controller.base import Backend, ControllerType
|
60
60
|
|
@@ -323,7 +323,9 @@ class QBLOXControllerInfo(BaseModel): # pragma: no cover
|
|
323
323
|
# Instrument management
|
324
324
|
# ==================================================================================================
|
325
325
|
class SequencerParams(BaseModel):
|
326
|
-
|
326
|
+
model_config = ConfigDict(validate_assignment=True)
|
327
|
+
|
328
|
+
nco_freq: float | None = Field(default=None, ge=-500e6, le=500e6)
|
327
329
|
gain_awg_path0: float | None = Field(default=None, ge=-1.0, le=1.0)
|
328
330
|
offset_awg_path0: float | None = Field(default=None, ge=-1.0, le=1.0)
|
329
331
|
gain_awg_path1: float | None = Field(default=None, ge=-1.0, le=1.0)
|
@@ -338,6 +340,8 @@ class SequencerParams(BaseModel):
|
|
338
340
|
|
339
341
|
|
340
342
|
class QcmParams(BaseModel):
|
343
|
+
model_config = ConfigDict(validate_assignment=True)
|
344
|
+
|
341
345
|
out0_offset: float | None = Field(default=None, ge=-2.5, le=2.5)
|
342
346
|
out1_offset: float | None = Field(default=None, ge=-2.5, le=2.5)
|
343
347
|
out2_offset: float | None = Field(default=None, ge=-2.5, le=2.5)
|
@@ -354,6 +358,8 @@ class QcmParams(BaseModel):
|
|
354
358
|
|
355
359
|
|
356
360
|
class QcmRfParams(BaseModel):
|
361
|
+
model_config = ConfigDict(validate_assignment=True)
|
362
|
+
|
357
363
|
out0_att: int | None = Field(default=None, ge=0, le=60, multiple_of=2)
|
358
364
|
out1_att: int | None = Field(default=None, ge=0, le=60, multiple_of=2)
|
359
365
|
|
@@ -375,6 +381,8 @@ class QcmRfParams(BaseModel):
|
|
375
381
|
|
376
382
|
|
377
383
|
class QrmRfParams(BaseModel):
|
384
|
+
model_config = ConfigDict(validate_assignment=True)
|
385
|
+
|
378
386
|
out0_att: int | None = Field(default=None, ge=0, le=60, multiple_of=2)
|
379
387
|
|
380
388
|
out0_in0_lo_freq: float | None = Field(default=None, gt=0)
|
@@ -11,10 +11,11 @@
|
|
11
11
|
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
12
|
# License for the specific language.
|
13
13
|
|
14
|
-
from typing import Literal, Self
|
14
|
+
from typing import Annotated, Any, Literal, Self
|
15
15
|
|
16
16
|
from pydantic import (
|
17
17
|
BaseModel,
|
18
|
+
BeforeValidator,
|
18
19
|
ConfigDict,
|
19
20
|
Field,
|
20
21
|
field_serializer,
|
@@ -31,10 +32,78 @@ from boulderopalscaleupsdk.third_party.quantum_machines.constants import (
|
|
31
32
|
QUA_CLOCK_CYCLE,
|
32
33
|
)
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
|
36
|
+
class OPXPortMapping(BaseModel):
|
37
|
+
type: Literal["controller"] = "controller"
|
38
|
+
controller_id: str
|
39
|
+
port_id: int
|
40
|
+
|
41
|
+
def to_native_opx_port_type(self) -> qm_config.NativeOPXPortType:
|
42
|
+
return qm_config.NativeOPXPortType(
|
43
|
+
controller_id=self.controller_id,
|
44
|
+
port_id=self.port_id,
|
45
|
+
)
|
46
|
+
|
47
|
+
@staticmethod
|
48
|
+
def from_native_opx_port_type(
|
49
|
+
port_type: qm_config.NativeOPXPortType,
|
50
|
+
) -> "OPXPortMapping":
|
51
|
+
return OPXPortMapping(
|
52
|
+
controller_id=port_type.controller_id,
|
53
|
+
port_id=port_type.port_id,
|
54
|
+
)
|
55
|
+
|
56
|
+
|
57
|
+
def ensure_opx_port_mapping(value: Any) -> Any:
|
58
|
+
match value:
|
59
|
+
case OPXPortMapping():
|
60
|
+
return value
|
61
|
+
case list([str(controller_id), float(port_id)]):
|
62
|
+
if not port_id.is_integer():
|
63
|
+
raise ValueError("port_id must be an integer")
|
64
|
+
return OPXPortMapping(controller_id=controller_id, port_id=int(port_id))
|
65
|
+
case list([str(controller_id), int(port_id)]):
|
66
|
+
return OPXPortMapping(controller_id=controller_id, port_id=port_id)
|
67
|
+
case tuple((str(controller_id), float(port_id))):
|
68
|
+
if not port_id.is_integer():
|
69
|
+
raise ValueError("port_id must be an integer")
|
70
|
+
return OPXPortMapping(controller_id=controller_id, port_id=int(port_id))
|
71
|
+
case tuple((str(controller_id), int(port_id))):
|
72
|
+
return OPXPortMapping(controller_id=controller_id, port_id=port_id)
|
73
|
+
case dict({"type": "controller", "controller_id": str(), "port_id": int() | float()}):
|
74
|
+
return OPXPortMapping.model_validate(value)
|
75
|
+
case _:
|
76
|
+
raise ValueError("Invalid Port Mapping")
|
77
|
+
|
78
|
+
|
79
|
+
OPXPortMappingLike = Annotated[
|
80
|
+
OPXPortMapping,
|
81
|
+
BeforeValidator(ensure_opx_port_mapping),
|
82
|
+
]
|
83
|
+
|
84
|
+
|
85
|
+
class OPX1000PortMapping(BaseModel):
|
86
|
+
type: Literal["frontend_module"] = "frontend_module"
|
87
|
+
controller_id: str
|
88
|
+
fem_id: int
|
89
|
+
port_id: int
|
90
|
+
|
91
|
+
def to_native_opx1000_port_type(self) -> qm_config.NativeOPX1000PortType:
|
92
|
+
return qm_config.NativeOPX1000PortType(
|
93
|
+
controller_id=self.controller_id,
|
94
|
+
fem_id=self.fem_id,
|
95
|
+
port_id=self.port_id,
|
96
|
+
)
|
97
|
+
|
98
|
+
@staticmethod
|
99
|
+
def from_native_opx1000_port_type(
|
100
|
+
port_type: qm_config.NativeOPX1000PortType,
|
101
|
+
) -> "OPX1000PortMapping":
|
102
|
+
return OPX1000PortMapping(
|
103
|
+
controller_id=port_type.controller_id,
|
104
|
+
fem_id=port_type.fem_id,
|
105
|
+
port_id=port_type.port_id,
|
106
|
+
)
|
38
107
|
|
39
108
|
|
40
109
|
class QuaProgram(BaseModel):
|
@@ -74,17 +143,17 @@ class OctaveConfig(qm_config.OctaveConfig121):
|
|
74
143
|
|
75
144
|
class DrivePortConfig(BaseModel):
|
76
145
|
port_type: Literal["drive"] = "drive"
|
77
|
-
port_mapping:
|
146
|
+
port_mapping: OPXPortMappingLike | OPX1000PortMapping
|
78
147
|
|
79
148
|
|
80
149
|
class FluxPortConfig(BaseModel):
|
81
150
|
port_type: Literal["flux"] = "flux"
|
82
|
-
port_mapping:
|
151
|
+
port_mapping: OPXPortMappingLike | OPX1000PortMapping
|
83
152
|
|
84
153
|
|
85
154
|
class ReadoutPortConfig(BaseModel):
|
86
155
|
port_type: Literal["readout"] = "readout"
|
87
|
-
port_mapping:
|
156
|
+
port_mapping: OPXPortMappingLike | OPX1000PortMapping
|
88
157
|
time_of_flight: DurationNsLike
|
89
158
|
smearing: DurationNsLike = Field(default=Duration(0, TimeUnit.NS))
|
90
159
|
|
@@ -119,22 +188,22 @@ class QuantumMachinesControllerInfo(BaseModel):
|
|
119
188
|
----------
|
120
189
|
controller_type : Literal[ControllerType.QUANTUM_MACHINES]
|
121
190
|
The type of controller, which is always `ControllerType.QUANTUM_MACHINES`.
|
122
|
-
controllers : dict[
|
123
|
-
A dictionary mapping controller references to their respective configurations.
|
191
|
+
controllers : dict[str, OPXControllerConfig | OPX1000ControllerConfig]
|
192
|
+
A dictionary mapping controller references (str) to their respective configurations.
|
124
193
|
The configurations can be either OPXControllerConfig or OPX1000ControllerConfig.
|
125
194
|
Derived from OPX Config.
|
126
|
-
octaves : dict[
|
127
|
-
A dictionary mapping octave references to their respective configurations.
|
195
|
+
octaves : dict[str, OctaveConfig]
|
196
|
+
A dictionary mapping octave references (str) to their respective configurations.
|
128
197
|
Derived from OPX Config.
|
129
|
-
port_config : dict[
|
130
|
-
A dictionary mapping port references to their respective port configurations.
|
198
|
+
port_config : dict[str, DrivePortConfig | FluxPortConfig | ReadoutPortConfig]
|
199
|
+
A dictionary mapping port references (str) to their respective port configurations.
|
131
200
|
The configurations can be DrivePortConfig, FluxPortConfig, or ReadoutPortConfig.
|
132
201
|
Not derived from OPX Config, this is our custom config.
|
133
202
|
"""
|
134
203
|
|
135
204
|
controller_type: Literal[ControllerType.QUANTUM_MACHINES] = ControllerType.QUANTUM_MACHINES
|
136
|
-
controllers: dict[
|
205
|
+
controllers: dict[str, OPXControllerConfig | OPX1000ControllerConfig] = Field(
|
137
206
|
default={},
|
138
207
|
)
|
139
|
-
octaves: dict[
|
140
|
-
port_config: dict[
|
208
|
+
octaves: dict[str, OctaveConfig] = Field(default={})
|
209
|
+
port_config: dict[str, DrivePortConfig | FluxPortConfig | ReadoutPortConfig]
|
@@ -191,8 +191,8 @@ class ComponentParameter(Generic[T]):
|
|
191
191
|
self.err_minus = None
|
192
192
|
self.err_plus = None
|
193
193
|
else:
|
194
|
-
self.err_minus = from_float(to_float(std)
|
195
|
-
self.err_plus = from_float(to_float(std)
|
194
|
+
self.err_minus = from_float(to_float(std))
|
195
|
+
self.err_plus = from_float(to_float(std))
|
196
196
|
if (
|
197
197
|
not isinstance(calibration_thresholds, EllipsisType)
|
198
198
|
and self.err_minus is not None
|
@@ -259,7 +259,7 @@ def _get_calibration_status_from_thresholds(
|
|
259
259
|
confidence_interval: float,
|
260
260
|
calibration_thresholds: CalibrationThresholds,
|
261
261
|
) -> CalibrationStatusT:
|
262
|
-
relative_uncertainty = abs(confidence_interval / value)
|
262
|
+
relative_uncertainty = 0.5 * abs(confidence_interval / value)
|
263
263
|
|
264
264
|
if relative_uncertainty < calibration_thresholds.good:
|
265
265
|
return "good"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
|
15
|
+
class ScaleUpServerError(Exception):
|
16
|
+
"""
|
17
|
+
Exception raised by client based on server behavior.
|
18
|
+
"""
|
19
|
+
|
20
|
+
def __init__(self, message: str):
|
21
|
+
super().__init__(message)
|
@@ -17,6 +17,7 @@ __all__ = [
|
|
17
17
|
"T1",
|
18
18
|
"T2",
|
19
19
|
"CWSIterable",
|
20
|
+
"CZSpectroscopyByBias",
|
20
21
|
"Chi01Scan",
|
21
22
|
"ConstantWaveform",
|
22
23
|
"DragCosineWaveform",
|
@@ -30,8 +31,10 @@ __all__ = [
|
|
30
31
|
"PowerRabi",
|
31
32
|
"PowerRabiEF",
|
32
33
|
"Ramsey",
|
34
|
+
"RamseyEF",
|
33
35
|
"RangeIterable",
|
34
|
-
"
|
36
|
+
"ReadoutClassifier",
|
37
|
+
"ReadoutOptimization",
|
35
38
|
"ResonatorSpectroscopy",
|
36
39
|
"ResonatorSpectroscopyByBias",
|
37
40
|
"ResonatorSpectroscopyByPower",
|
@@ -53,12 +56,15 @@ from .common import (
|
|
53
56
|
LogspaceIterable,
|
54
57
|
RangeIterable,
|
55
58
|
)
|
59
|
+
from .cz_spectroscopy_by_bias import CZSpectroscopyByBias
|
56
60
|
from .drag_leakage_calibration import DragLeakageCalibration
|
57
61
|
from .fine_amplitude_calibration import FineAmplitudeCalibration
|
58
62
|
from .power_rabi import PowerRabi
|
59
63
|
from .power_rabi_ef import PowerRabiEF
|
60
64
|
from .ramsey import Ramsey
|
61
|
-
from .
|
65
|
+
from .ramsey_ef import RamseyEF
|
66
|
+
from .readout_classifier import ReadoutClassifier
|
67
|
+
from .readout_optimization import ReadoutOptimization
|
62
68
|
from .resonator_spectroscopy import ResonatorSpectroscopy
|
63
69
|
from .resonator_spectroscopy_by_bias import ResonatorSpectroscopyByBias
|
64
70
|
from .resonator_spectroscopy_by_power import ResonatorSpectroscopyByPower
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from typing import Literal
|
15
|
+
|
16
|
+
from pydantic import PrivateAttr
|
17
|
+
|
18
|
+
from .common import Experiment
|
19
|
+
|
20
|
+
DEFAULT_PREP_PADDING_NS = 16
|
21
|
+
DEFAULT_MEASUREMENT_PADDING_NS = 16
|
22
|
+
DEFAULT_MIN_DURATION_NS = 16
|
23
|
+
DEFAULT_MAX_DURATION_NS = 200
|
24
|
+
DEFAULT_TIME_STEP_NS = 8
|
25
|
+
DEFAULT_RECYCLE_DELAY_NS = 500_000
|
26
|
+
DEFAULT_SHOT_COUNT = 200
|
27
|
+
|
28
|
+
|
29
|
+
class CZSpectroscopyByBias(Experiment):
|
30
|
+
"""
|
31
|
+
Parameters for running a Ramsey experiment.
|
32
|
+
|
33
|
+
Parameters
|
34
|
+
----------
|
35
|
+
control_transmon : str
|
36
|
+
The control transmon to target in the experiment.
|
37
|
+
target_transmon : str
|
38
|
+
The target transmon to pair with the control transmon.
|
39
|
+
min_vp : float
|
40
|
+
The minimum voltage point, in volts.
|
41
|
+
max_vp : float
|
42
|
+
The maximum voltage point, in volts.
|
43
|
+
num_vp : int
|
44
|
+
The number of voltage points to sample.
|
45
|
+
min_duration_ns : int
|
46
|
+
The minimum duration for the pulse in the experiment, in nanoseconds.
|
47
|
+
max_duration_ns : int
|
48
|
+
The maximum duration for the pulse in the experiment, in nanoseconds.
|
49
|
+
duration_step_ns : int
|
50
|
+
The step size for the duration, in nanoseconds.
|
51
|
+
prep_padding_ns : int
|
52
|
+
The padding to apply before the CZ pulse, in nanoseconds.
|
53
|
+
measurement_padding_ns : int
|
54
|
+
The padding to apply after the CZ pulse, in nanoseconds.
|
55
|
+
recycle_delay_ns : float
|
56
|
+
The delay time between consecutive shots of the experiment, in nanoseconds.
|
57
|
+
Defaults to 500000 ns.
|
58
|
+
shot_count : int,
|
59
|
+
The number of shots to be taken in the experiment.
|
60
|
+
Defaults to 200.
|
61
|
+
batch_analysis : bool
|
62
|
+
Whether to perform batch analysis on the results.
|
63
|
+
spectroscopy_waveform : ConstantWaveform
|
64
|
+
The waveform to use in the spectroscopy pulse.
|
65
|
+
"""
|
66
|
+
|
67
|
+
_experiment_name: str = PrivateAttr("cz_spectroscopy_by_bias")
|
68
|
+
|
69
|
+
control_transmon: str
|
70
|
+
target_transmon: str
|
71
|
+
coupler: str
|
72
|
+
min_vp: float
|
73
|
+
max_vp: float
|
74
|
+
num_vp: int
|
75
|
+
coupler_flux_vp: float
|
76
|
+
min_duration_ns: int = DEFAULT_MIN_DURATION_NS
|
77
|
+
max_duration_ns: int = DEFAULT_MAX_DURATION_NS
|
78
|
+
duration_step_ns: int = DEFAULT_TIME_STEP_NS
|
79
|
+
prep_padding_ns: int = DEFAULT_PREP_PADDING_NS
|
80
|
+
measurement_padding_ns: int = DEFAULT_MEASUREMENT_PADDING_NS
|
81
|
+
recycle_delay_ns: int = DEFAULT_RECYCLE_DELAY_NS
|
82
|
+
shot_count: int = DEFAULT_SHOT_COUNT
|
83
|
+
batch_analysis: bool = False
|
84
|
+
update: Literal["auto", "off", "prompt"] = "auto"
|
@@ -44,7 +44,7 @@ class PowerRabi(Experiment):
|
|
44
44
|
shot_count : int, optional
|
45
45
|
The number of shots to take. Defaults to 400.
|
46
46
|
pulse_vp : float, optional
|
47
|
-
The voltage per pulse, in
|
47
|
+
The voltage per pulse, in volts. Defaults to the amplitude of the X gate.
|
48
48
|
measure_waveform : ConstantWaveform or None, optional
|
49
49
|
The waveform to use for the measurement pulse.
|
50
50
|
Defaults to the measurement defcal.
|
@@ -44,7 +44,7 @@ class PowerRabiEF(Experiment):
|
|
44
44
|
shot_count : int, optional
|
45
45
|
The number of shots to take. Defaults to 400.
|
46
46
|
pulse_vp : float, optional
|
47
|
-
The voltage per pulse, in
|
47
|
+
The voltage per pulse, in volts. Defaults to the amplitude of the X gate.
|
48
48
|
measure_waveform : ConstantWaveform or None, optional
|
49
49
|
The waveform to use for the measurement pulse.
|
50
50
|
Defaults to the measurement defcal.
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Copyright 2025 Q-CTRL. All rights reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Q-CTRL Terms of service (the "License"). Unauthorized
|
4
|
+
# copying or use of this file, via any medium, is strictly prohibited.
|
5
|
+
# Proprietary and confidential. You may not use this file except in compliance
|
6
|
+
# with the License. You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# https://q-ctrl.com/terms
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS. See the
|
12
|
+
# License for the specific language.
|
13
|
+
|
14
|
+
from typing import Literal
|
15
|
+
|
16
|
+
from pydantic import PrivateAttr
|
17
|
+
|
18
|
+
from .common import Experiment
|
19
|
+
from .waveforms import ConstantWaveform
|
20
|
+
|
21
|
+
|
22
|
+
class RamseyEF(Experiment):
|
23
|
+
"""
|
24
|
+
Parameters for running a EF Ramsey experiment.
|
25
|
+
|
26
|
+
Attributes
|
27
|
+
----------
|
28
|
+
transmon : str
|
29
|
+
The reference for the transmon to target.
|
30
|
+
min_delay_ns : int
|
31
|
+
The minimum delay time, in nanoseconds.
|
32
|
+
max_delay_ns : int
|
33
|
+
The maximum delay time, in nanoseconds.
|
34
|
+
delay_step_ns : int
|
35
|
+
The step for generating the list of delays, in nanoseconds.
|
36
|
+
virtual_detuning : float
|
37
|
+
The virtual detuning added between sx_ef pulses, in Hz.
|
38
|
+
recycle_delay_ns : int, optional
|
39
|
+
The delay between consecutive shots, in nanoseconds. Defaults to 200,000 ns.
|
40
|
+
shot_count : int, optional
|
41
|
+
The number of shots to take. Defaults to 400.
|
42
|
+
measure_waveform : ConstantWaveform or None, optional
|
43
|
+
The waveform to use for the measurement pulse.
|
44
|
+
Defaults to the measurement defcal.
|
45
|
+
run_mixer_calibration: bool
|
46
|
+
Whether to run mixer calibrations before running a program. Defaults to False.
|
47
|
+
update : "auto" or "off" or "prompt", optional
|
48
|
+
How the device should be updated after an experiment run. Defaults to auto.
|
49
|
+
"""
|
50
|
+
|
51
|
+
_experiment_name: str = PrivateAttr("ramsey_ef")
|
52
|
+
|
53
|
+
transmon: str
|
54
|
+
min_delay_ns: int
|
55
|
+
max_delay_ns: int
|
56
|
+
delay_step_ns: int
|
57
|
+
virtual_detuning: float
|
58
|
+
recycle_delay_ns: int = 200_000
|
59
|
+
shot_count: int = 400
|
60
|
+
measure_waveform: ConstantWaveform | None = None
|
61
|
+
run_mixer_calibration: bool = False
|
62
|
+
update: Literal["auto", "off", "prompt"] = "auto"
|
@@ -19,9 +19,13 @@ from .common import Experiment
|
|
19
19
|
from .waveforms import ConstantWaveform
|
20
20
|
|
21
21
|
|
22
|
-
class
|
22
|
+
class ReadoutClassifier(Experiment):
|
23
23
|
"""
|
24
|
-
Parameters for
|
24
|
+
Parameters for training a readout classifier.
|
25
|
+
|
26
|
+
This does not optimize the readout pulse itself.
|
27
|
+
The measure waveform is fixed (provided or using the device's default).
|
28
|
+
To optimize the readout pulse use ReadoutOptimization.
|
25
29
|
|
26
30
|
Attributes
|
27
31
|
----------
|
@@ -40,7 +44,7 @@ class ReadoutClassifierCalibration(Experiment):
|
|
40
44
|
How the device should be updated after an experiment run. Defaults to auto.
|
41
45
|
"""
|
42
46
|
|
43
|
-
_experiment_name: str = PrivateAttr("
|
47
|
+
_experiment_name: str = PrivateAttr("readout_classifier")
|
44
48
|
|
45
49
|
transmon: str
|
46
50
|
recycle_delay_ns: int = 200_000
|