labcore.protocols.base#
Functions
|
Select the hardware platform for subsequent protocol execution. |
|
Classes
|
A named sequence of operations that can be executed. |
|
Result of a single named check in evaluate(). |
|
A conditional decision point that routes execution to different branches. |
Base class for stateful correction strategies. |
|
|
Platform-aware correction strategy knob. |
|
Return type for ProtocolOperation.evaluate() and correct(). |
|
Return status for ProtocolOperation.evaluate() |
|
|
|
|
|
|
|
Base class for protocol parameters with platform-specific getter/setter methods. |
A composite operation that groups multiple operations together. |
- class labcore.protocols.base.BranchBase(name: str = 'Branch')[source]#
Bases:
objectA named sequence of operations that can be executed.
Branches can contain: - Operations (ProtocolOperation instances) - Conditions (conditional routing to other branches)
- Parameters:
name – Display name for this branch
Example
>>> main_branch = BranchBase("MainCalibration") >>> main_branch.append(ResonatorSpectroscopy(params)) >>> main_branch.append(SaturationSpectroscopy(params))
- append(item: ProtocolOperation | Condition) BranchBase[source]#
Add an operation or condition to this branch
- extend(items: list[ProtocolOperation | Condition]) BranchBase[source]#
Add multiple operations/conditions to this branch
- class labcore.protocols.base.CheckResult(name: str, passed: bool, description: str)[source]#
Bases:
objectResult of a single named check in evaluate().
- class labcore.protocols.base.Condition(condition: Callable[[], bool], true_branch: BranchBase, false_branch: BranchBase, name: str = 'Condition')[source]#
Bases:
objectA conditional decision point that routes execution to different branches.
During protocol execution, the condition is evaluated and either true_branch or false_branch is executed.
- Parameters:
condition – Callable returning bool to determine which branch
true_branch – Branch to execute if condition is True
false_branch – Branch to execute if condition is False
name – Optional name for this condition (for logging/reporting)
Example
>>> res_snr = params['resonator']['snr'] >>> >>> high_snr_branch = BranchBase("HighSNR") >>> high_snr_branch.append(PiSpectroscopy(params)) >>> >>> low_snr_branch = BranchBase("LowSNR") >>> low_snr_branch.append(PowerRabi(params)) >>> low_snr_branch.append(PiSpectroscopy(params)) >>> >>> condition = Condition( >>> condition=lambda: res_snr() > 5.0, >>> true_branch=high_snr_branch, >>> false_branch=low_snr_branch, >>> name="SNR Check" >>> )
- evaluate() BranchBase[source]#
Evaluate condition and return the branch to execute
- taken_branch: BranchBase | None#
- class labcore.protocols.base.Correction[source]#
Bases:
objectBase class for stateful correction strategies.
Subclass this and attach an instance to the operation in
__init__. The instance persists across retry attempts so that stateful strategies (e.g. stepping through a list of frequency windows) work correctly.Example:
class FrequencySweepCorrection(Correction): name = "scan_next_frequency_window" description = "Step through candidate frequency windows" triggered_by = "peak_exists" def __init__(self, freq_param, windows: list[float]): self.freq_param = freq_param self.windows = windows self._idx = 0 def can_apply(self) -> bool: return self._idx < len(self.windows) def apply(self) -> None: self.freq_param(self.windows[self._idx]) self._idx += 1
- class labcore.protocols.base.CorrectionParameter(name: str, params: Any, description: str, platform_type: PlatformTypes | None = None)[source]#
Bases:
ProtocolParameterBasePlatform-aware correction strategy knob.
Use this instead of ProtocolParameterBase for parameters that control correction strategies (e.g. window size, step count, noise tolerance). May have platform-specific units or scaling — implement the platform getter/setter methods for any unit conversions needed.
Subclass exactly like ProtocolParameterBase.
- class labcore.protocols.base.EvaluateResult(status: OperationStatus, checks: list[CheckResult] = <factory>)[source]#
Bases:
objectReturn type for ProtocolOperation.evaluate() and correct().
- checks: list[CheckResult]#
- status: OperationStatus#
- class labcore.protocols.base.OperationStatus(*values)[source]#
Bases:
EnumReturn status for ProtocolOperation.evaluate()
Indicates what the protocol executor should do next with this operation.
- FAILURE = 'failure'#
- RETRY = 'retry'#
- SUCCESS = 'success'#
- class labcore.protocols.base.ParamImprovement(old_value: 'Any', new_value: 'Any', param: 'ProtocolParameterBase')[source]#
Bases:
object- param: ProtocolParameterBase#
- class labcore.protocols.base.PlatformTypes(*values)[source]#
Bases:
Enum- DUMMY = 3#
- OPX = 1#
- QICK = 2#
- class labcore.protocols.base.ProtocolBase(report_path: Path = PosixPath('.'))[source]#
Bases:
object- root_branch: BranchBase | None#
- class labcore.protocols.base.ProtocolOperation[source]#
Bases:
object- DEFAULT_MAX_ATTEMPTS = 100#
- correct(result: EvaluateResult) EvaluateResult[source]#
Apply parameter changes based on the evaluation result.
This is the only place where parameter values should be modified.
Default implementation: - Appends a check summary table to the report. - On RETRY: applies registered corrections for each failed check.
If any correction’s can_apply() returns False, escalates to FAILURE.
On SUCCESS / FAILURE: no-op (override to apply found values on SUCCESS).
Override to apply found values on SUCCESS or implement complex correction logic. Call super().correct(result) first to get check reporting and default RETRY correction handling, then handle SUCCESS.
- Parameters:
result – The EvaluateResult returned by evaluate().
- Returns:
Possibly modified EvaluateResult (e.g. RETRY escalated to FAILURE when a correction is exhausted).
- correction_params: dict[str, CorrectionParameter]#
- evaluate() EvaluateResult[source]#
Assess operation results and return named check outcomes.
Default implementation runs all checks registered via _register_check(). Returns SUCCESS if all checks pass, RETRY if any fail.
Override for complex logic (conditional checks, custom status rules). Overrides should still return an EvaluateResult with CheckResult objects so that reports and the default correct() work correctly.
- Returns:
EvaluateResult containing the status and individual check outcomes.
- execute() EvaluateResult[source]#
Execute the full operation workflow: measure -> load_data -> analyze -> evaluate -> correct.
- Returns:
EvaluateResult from correct(), which may differ from evaluate()’s result (e.g. RETRY escalated to FAILURE when a correction is exhausted).
- improvements: list[ParamImprovement]#
- input_params: dict[str, ProtocolParameterBase]#
- output_params: dict[str, ProtocolParameterBase]#
- platform_type: PlatformTypes | None#
- class labcore.protocols.base.ProtocolParameterBase(name: str, params: Any, description: str, platform_type: PlatformTypes | None = None)[source]#
Bases:
objectBase class for protocol parameters with platform-specific getter/setter methods.
Subclasses must implement the platform-specific getter/setter methods: - _qick_getter() / _qick_setter(value) for QICK platform - _opx_getter() / _opx_setter(value) for OPX platform - _dummy_getter() / _dummy_setter(value) for DUMMY platform
These methods should directly call the QCoDeS-style parameter with: - Get: my_param() - Set: my_param(value)
Example
>>> @dataclass >>> class QubitFrequency(ProtocolParameterBase): ... name: str = field(default="Qubit IF", init=False) ... description: str = field(default="Qubit intermediate frequency", init=False) ... ... def _qick_getter(self): ... return self.params.qubit.f_ge() ... ... def _qick_setter(self, value): ... return self.params.qubit.f_ge(value) ... ... def _opx_getter(self): ... return self.params.qubit.frequency() ... ... def _opx_setter(self, value): ... return self.params.qubit.frequency(value)
- platform_type: PlatformTypes | None = None#
- class labcore.protocols.base.SuperOperationBase[source]#
Bases:
ProtocolOperationA composite operation that groups multiple operations together.
SuperOperations execute a sequence of operations as a single unit, sharing the same retry mechanism. If any sub-operation fails, the entire SuperOperation can be retried.
Key features: - All sub-operations execute in sequence - Retry logic applies to the entire group - Reports are aggregated under the SuperOperation section - Branching (Conditions) is NOT permitted in SuperOperations - Protocol treats it the same as a regular operation
Subclasses must: 1. Call super().__init__() in their __init__ 2. Set self.operations to a list of ProtocolOperation instances 3. NOT include any Condition instances in self.operations
Example
>>> class CalibrationSuite(SuperOperationBase): ... def __init__(self, params): ... super().__init__() ... self.operations = [ ... ResonatorSpectroscopy(params), ... PowerRabi(params), ... PiSpectroscopy(params) ... ] ... ... def evaluate(self) -> OperationStatus: ... # All operations succeeded, check aggregate quality ... if all_calibrations_good(): ... return OperationStatus.SUCCESS ... else: ... return OperationStatus.RETRY
- correct(result: EvaluateResult) EvaluateResult[source]#
Apply super-operation level corrections. Override to implement super-level parameter changes. Default: no-op (sub-operations handle their own corrections inside their own execute() calls).
- execute() EvaluateResult[source]#
Execute all sub-operations in sequence and aggregate their reports.
This method overrides ProtocolOperation.execute() to iterate through all sub-operations instead of calling measure/load_data/analyze.
- Returns:
EvaluateResult from correct() after all sub-operations complete.
- operations: list[ProtocolOperation]#
- labcore.protocols.base.select_platform(platform: PlatformTypes | str) None[source]#
Select the hardware platform for subsequent protocol execution.
Must be called once before instantiating any
ProtocolBasesubclass. Accepts either aPlatformTypesmember or its name as a string (case-insensitive).