Source code for qblox_scheduler

# Licensed according to the LICENSE file on the main branch
#
# Copyright 2020-2025, Quantify Consortium
# Copyright 2025, Qblox B.V.
"""
.. list-table::
    :header-rows: 1
    :widths: auto

    * - Import alias
      - Target
    * - :class:`.QuantumDevice`
      - :class:`!qblox_scheduler.QuantumDevice`
    * - :class:`.Resource`
      - :class:`!qblox_scheduler.Resource`
    * - :class:`.ClockResource`
      - :class:`!qblox_scheduler.ClockResource`
    * - :class:`.BasebandClockResource`
      - :class:`!qblox_scheduler.BasebandClockResource`
    * - :class:`.DigitalClockResource`
      - :class:`!qblox_scheduler.DigitalClockResource`
    * - :class:`.Operation`
      - :class:`!qblox_scheduler.Operation`
    * - :obj:`.structure`
      - :obj:`!qblox_scheduler.structure`
    * - :class:`.BasicElectronicNVElement`
      - :class:`!qblox_scheduler.BasicElectronicNVElement`
    * - :class:`.BasicSpinElement`
      - :class:`!qblox_scheduler.BasicSpinElement`
    * - :class:`.BasicTransmonElement`
      - :class:`!qblox_scheduler.BasicTransmonElement`
    * - :class:`.CompositeSquareEdge`
      - :class:`!qblox_scheduler.CompositeSquareEdge`
    * - :class:`.InstrumentCoordinator`
      - :class:`!qblox_scheduler.InstrumentCoordinator`
    * - :class:`.GenericInstrumentCoordinatorComponent`
      - :class:`!qblox_scheduler.GenericInstrumentCoordinatorComponent`
    * - :class:`.SerialCompiler`
      - :class:`!qblox_scheduler.SerialCompiler`
    * - :class:`.MockLocalOscillator`
      - :class:`!qblox_scheduler.MockLocalOscillator`
    * - :class:`.SpinEdge`
      - :class:`!qblox_scheduler.SpinEdge`
"""

import importlib
import warnings
from typing import TYPE_CHECKING

from ._version import __version__
from .backends.types.common import HardwareDistortionCorrection, MixerCorrections
from .backends.types.qblox.calibration import (
    ComplexInputGain,
    DigitizationThresholds,
    InputAttenuation,
    NetZeroPulseParameters,
    OutputAttenuation,
    QbloxHardwareDistortionCorrection,
    QbloxMixerCorrections,
    RealInputGain,
)
from .backends.types.qblox.filters import (
    ExpOvershootFilter,
    FIRFilter,
    IHPFilter,
    QbloxRealTimeFilter,
)
from .data_dir import OutputDirectoryManager
from .device_under_test.quantum_device import DeviceElement, Edge, QuantumDevice
from .helpers.mock_instruments import MockLocalOscillator
from .operations.acquisition_library import (
    Acquisition,
    DualThresholdedTriggerCount,
    IQIntegration,
    IQIntegrationMixed,
    NumericalSeparatedWeightedIntegration,
    NumericalWeightedIntegration,
    SSBIntegrationComplex,
    ThresholdedAcquisition,
    ThresholdedIQIntegration,
    ThresholdedIQIntegrationMixed,
    ThresholdedTriggerCount,
    Timetag,
    TimetagTrace,
    Trace,
    TriggerCount,
    TriggerCountDistribution,
    WeightedIntegratedSeparated,
    WeightedThresholdedAcquisition,
)
from .operations.conditional_reset import ConditionalReset
from .operations.control_flow_library import (
    ConditionalOperation,
    ControlFlowSpec,
    LoopStrategy,
)
from .operations.expressions import DType
from .operations.gate_library import (
    CNOT,
    CZ,
    X90,
    Y90,
    Z90,
    H,
    Measure,
    Reset,
    Rxy,
    Rz,
    S,
    SDagger,
    T,
    TDagger,
    X,
    Y,
    Z,
)
from .operations.hardware_operations import (
    InlineQ1ASM,
)
from .operations.hardware_operations.pulse_library import LatchReset, SimpleNumericalPulse
from .operations.loop_domains import arange, linspace
from .operations.nv_native_library import ChargeReset, CRCount
from .operations.operation import Operation
from .operations.pulse_compensation_library import (
    PulseCompensation,
)
from .operations.pulse_library import (
    ChirpPulse,
    DRAGPulse,
    GaussPulse,
    IdlePulse,
    MarkerPulse,
    NumericalPulse,
    RampPulse,
    ReferenceMagnitude,
    ResetClockPhase,
    SetClockFrequency,
    ShiftClockPhase,
    SkewedHermitePulse,
    SoftSquarePulse,
    SquarePulse,
    StaircasePulse,
    SuddenNetZeroPulse,
    Timestamp,
    VoltageOffset,
)
from .qblox.hardware_agent import HardwareAgent
from .resources import (
    BasebandClockResource,
    ClockResource,
    DigitalClockResource,
    Resource,
)
from .schedule import Schedule
from .schedules.schedule import CompiledSchedule, Schedulable
from .segments.loops import Loop
from .segments.parameters import (
    Callback,
    SetHardwareDescriptionField,
    SetHardwareOption,
    SetParameter,
)

if TYPE_CHECKING:
    # These are only imported eagerly for static type checkers (mypy/pyright) so that
    # e.g. `BasicTransmonElement(...)` resolves to the real class instead of `object`.
    # all of these are deprecated and will be removed starting the 1.0 release.
    from .analysis.base_analysis import Basic2DAnalysis, BasicAnalysis
    from .analysis.cosine_analysis import CosineAnalysis
    from .analysis.data_handling import AnalysisDataContainer
    from .analysis.helpers import acq_coords_to_dims
    from .analysis.interpolation_analysis import InterpolationAnalysis2D
    from .analysis.optimization_analysis import OptimizationAnalysis
    from .analysis.single_qubit_timedomain import (
        AllXYAnalysis,
        EchoAnalysis,
        RabiAnalysis,
        RamseyAnalysis,
        T1Analysis,
    )
    from .analysis.spectroscopy_analysis import ResonatorSpectroscopyAnalysis
    from .backends import SerialCompiler
    from .device_under_test import (
        BasicElectronicNVElement,
        BasicSpinElement,
        BasicTransmonElement,
        ChargeSensor,
        CompositeSquareEdge,
        SpinEdge,
    )
    from .instrument_coordinator import InstrumentCoordinator
    from .instrument_coordinator.components.generic import GenericInstrumentCoordinatorComponent
    from .operations.control_flow_library import ControlFlowOperation, LoopOperation
    from .operations.hardware_operations import (
        long_chirp_pulse,
        long_ramp_pulse,
        long_square_pulse,
        staircase_pulse,
    )
    from .operations.pulse_library import ReferenceMagnitude, WindowOperation
    from .schedules.spectroscopy_schedules import (
        heterodyne_spec_sched,
        heterodyne_spec_sched_nco,
        nv_dark_esr_sched,
        two_tone_spec_sched,
        two_tone_spec_sched_nco,
    )
    from .schedules.timedomain_schedules import (
        allxy_sched,
        echo_sched,
        rabi_pulse_sched,
        rabi_sched,
        ramsey_sched,
        readout_calibration_sched,
        t1_sched,
    )
    from .schedules.trace_schedules import (
        trace_schedule,
        trace_schedule_circuit_layer,
        two_tone_trace_schedule,
    )

# In preparation of the 1.0 release, we mark some of the public API as deprecated
# because they will be either removed entirely, or marked as a strictly internal interface
_DEPRECATED_ATTRIBUTES: dict[str, tuple[str, str, str]] = {
    # analysis classes (move_to_other_repo)
    "Basic2DAnalysis": (".analysis.base_analysis", "Basic2DAnalysis", "move_to_other_repo"),
    "BasicAnalysis": (".analysis.base_analysis", "BasicAnalysis", "move_to_other_repo"),
    "CosineAnalysis": (".analysis.cosine_analysis", "CosineAnalysis", "move_to_other_repo"),
    "AnalysisDataContainer": (
        ".analysis.data_handling",
        "AnalysisDataContainer",
        "move_to_other_repo",
    ),
    "acq_coords_to_dims": (".analysis.helpers", "acq_coords_to_dims", "move_to_other_repo"),
    "InterpolationAnalysis2D": (
        ".analysis.interpolation_analysis",
        "InterpolationAnalysis2D",
        "move_to_other_repo",
    ),
    "OptimizationAnalysis": (
        ".analysis.optimization_analysis",
        "OptimizationAnalysis",
        "move_to_other_repo",
    ),
    "AllXYAnalysis": (".analysis.single_qubit_timedomain", "AllXYAnalysis", "move_to_other_repo"),
    "EchoAnalysis": (".analysis.single_qubit_timedomain", "EchoAnalysis", "move_to_other_repo"),
    "RabiAnalysis": (".analysis.single_qubit_timedomain", "RabiAnalysis", "move_to_other_repo"),
    "RamseyAnalysis": (".analysis.single_qubit_timedomain", "RamseyAnalysis", "move_to_other_repo"),
    "T1Analysis": (".analysis.single_qubit_timedomain", "T1Analysis", "move_to_other_repo"),
    "ResonatorSpectroscopyAnalysis": (
        ".analysis.spectroscopy_analysis",
        "ResonatorSpectroscopyAnalysis",
        "move_to_other_repo",
    ),
    # schedule functions (removed)
    "heterodyne_spec_sched": (
        ".schedules.spectroscopy_schedules",
        "heterodyne_spec_sched",
        "removed",
    ),
    "heterodyne_spec_sched_nco": (
        ".schedules.spectroscopy_schedules",
        "heterodyne_spec_sched_nco",
        "removed",
    ),
    "nv_dark_esr_sched": (".schedules.spectroscopy_schedules", "nv_dark_esr_sched", "removed"),
    "two_tone_spec_sched": (".schedules.spectroscopy_schedules", "two_tone_spec_sched", "removed"),
    "two_tone_spec_sched_nco": (
        ".schedules.spectroscopy_schedules",
        "two_tone_spec_sched_nco",
        "removed",
    ),
    "allxy_sched": (".schedules.timedomain_schedules", "allxy_sched", "removed"),
    "echo_sched": (".schedules.timedomain_schedules", "echo_sched", "removed"),
    "rabi_pulse_sched": (".schedules.timedomain_schedules", "rabi_pulse_sched", "removed"),
    "rabi_sched": (".schedules.timedomain_schedules", "rabi_sched", "removed"),
    "ramsey_sched": (".schedules.timedomain_schedules", "ramsey_sched", "removed"),
    "readout_calibration_sched": (
        ".schedules.timedomain_schedules",
        "readout_calibration_sched",
        "removed",
    ),
    "t1_sched": (".schedules.timedomain_schedules", "t1_sched", "removed"),
    "trace_schedule": (".schedules.trace_schedules", "trace_schedule", "removed"),
    "trace_schedule_circuit_layer": (
        ".schedules.trace_schedules",
        "trace_schedule_circuit_layer",
        "removed",
    ),
    "two_tone_trace_schedule": (".schedules.trace_schedules", "two_tone_trace_schedule", "removed"),
    "long_chirp_pulse": (".operations.hardware_operations", "long_chirp_pulse", "removed"),
    "long_ramp_pulse": (".operations.hardware_operations", "long_ramp_pulse", "removed"),
    "long_square_pulse": (".operations.hardware_operations", "long_square_pulse", "removed"),
    "staircase_pulse": (".operations.hardware_operations", "staircase_pulse", "removed"),
    "WindowOperation": (".operations.pulse_library", "WindowOperation", "removed"),
    # other: removed
    "ReferenceMagnitude": (".operations.pulse_library", "ReferenceMagnitude", "removed"),
    # use different interface than LoopOperation
    "LoopOperation": (".operations.control_flow_library", "LoopOperation", "loop_other_interface"),
    # internal interfaces
    "SerialCompiler": (".backends", "SerialCompiler", "internal"),
    "InstrumentCoordinator": (".instrument_coordinator", "InstrumentCoordinator", "internal"),
    "GenericInstrumentCoordinatorComponent": (
        ".instrument_coordinator.components.generic",
        "GenericInstrumentCoordinatorComponent",
        "internal",
    ),
    "ControlFlowOperation": (
        ".operations.control_flow_library",
        "ControlFlowOperation",
        "internal",
    ),
    "ControlFlowSpec": (
        ".operations.control_flow_library",
        "ControlFlowSpec",
        "internal",
    ),
    # will be moved to another repository soon.
    "BasicElectronicNVElement": (
        ".device_under_test",
        "BasicElectronicNVElement",
        "move_to_other_repo",
    ),
    "BasicSpinElement": (".device_under_test", "BasicSpinElement", "move_to_other_repo"),
    "BasicTransmonElement": (".device_under_test", "BasicTransmonElement", "move_to_other_repo"),
    "ChargeSensor": (".device_under_test", "ChargeSensor", "move_to_other_repo"),
    "CompositeSquareEdge": (".device_under_test", "CompositeSquareEdge", "move_to_other_repo"),
    "SpinEdge": (".device_under_test", "SpinEdge", "move_to_other_repo"),
}


def __getattr__(name: str) -> object:
    try:
        module_path, attr_name, reason = _DEPRECATED_ATTRIBUTES[name]
    except KeyError:
        raise AttributeError(f"module {__name__!r} has no attribute {name!r}") from None

    match reason:
        case "internal":
            message = (
                f"Importing '{name}' directly from '{__name__}' is deprecated. "
                f"'{name}' is considered an internal interface and will no longer be "
                f"exported from '{__name__}' starting with the 1.0 release. "
                f"Import it from '{__name__}{module_path}' instead."
            )
        case "loop_other_interface":
            message = (
                "Using LoopOperation directly is deprecated and "
                "will be removed starting with the 1.0 release."
                "please use the `with schedule.loop(...)` syntax"
                "instead."
            )
        case "move_to_other_repo":
            message = (
                f"'{name}' will be removed in 1.0 and made available in a separate repository"
                ", see release notes for more details."
            )
        case _:
            message = (
                f"Importing '{name}' directly from '{__name__}' is deprecated and "
                f"'{name}' will be removed starting with the 1.0 release."
            )

    warnings.warn(message, FutureWarning, stacklevel=2)

    module = importlib.import_module(module_path, __name__)
    return getattr(module, attr_name)


__all__ = [  # noqa: RUF022
    # from ._version
    "__version__",
    # from .analysis.base_analysis (deprecated, resolved via __getattr__)
    "Basic2DAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    "BasicAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .analysis.cosine_analysis (deprecated, resolved via __getattr__)
    "CosineAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .analysis.data_handling (deprecated, resolved via __getattr__)
    "AnalysisDataContainer",  # pyright: ignore[reportUnsupportedDunderAll]
    "OutputDirectoryManager",
    # from .analysis.helpers (deprecated, resolved via __getattr__)
    "acq_coords_to_dims",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .analysis.interpolation_analysis (deprecated, resolved via __getattr__)
    "InterpolationAnalysis2D",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .analysis.optimization_analysis (deprecated, resolved via __getattr__)
    "OptimizationAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .analysis.single_qubit_timedomain (deprecated, resolved via __getattr__)
    "AllXYAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    "EchoAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    "RabiAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    "RamseyAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    "T1Analysis",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .analysis.spectroscopy_analysis (deprecated, resolved via __getattr__)
    "ResonatorSpectroscopyAnalysis",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .backends (deprecated, resolved via __getattr__)
    "SerialCompiler",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .backends.types.qblox.calibration
    "ComplexInputGain",
    "DigitizationThresholds",
    "InputAttenuation",
    "NetZeroPulseParameters",
    "OutputAttenuation",
    "QbloxHardwareDistortionCorrection",
    "QbloxMixerCorrections",
    "HardwareDistortionCorrection",
    "MixerCorrections",
    "RealInputGain",
    # from .backends.types.qblox.filters
    "ExpOvershootFilter",
    "FIRFilter",
    "IHPFilter",
    "QbloxRealTimeFilter",
    # from .device_under_test
    "BasicElectronicNVElement",  # pyright: ignore[reportUnsupportedDunderAll]
    "BasicSpinElement",  # pyright: ignore[reportUnsupportedDunderAll]
    "BasicTransmonElement",  # pyright: ignore[reportUnsupportedDunderAll]
    "ChargeSensor",  # pyright: ignore[reportUnsupportedDunderAll]
    "CompositeSquareEdge",  # pyright: ignore[reportUnsupportedDunderAll]
    "DeviceElement",
    "Edge",
    "QuantumDevice",
    "SpinEdge",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .segments.loops
    "Loop",
    # from .segments.parameters
    "Callback",
    "SetHardwareDescriptionField",
    "SetHardwareOption",
    "SetParameter",
    # from .helpers.mock_instruments
    "MockLocalOscillator",
    # from .instrument_coordinator (deprecated, resolved via __getattr__)
    "InstrumentCoordinator",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .instrument_coordinator.components.generic (deprecated, resolved via __getattr__)
    "GenericInstrumentCoordinatorComponent",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .operations.acquisition_library
    "Acquisition",
    "DualThresholdedTriggerCount",
    "IQIntegration",
    "IQIntegrationMixed",
    "NumericalSeparatedWeightedIntegration",
    "NumericalWeightedIntegration",
    "SSBIntegrationComplex",
    "ThresholdedAcquisition",
    "ThresholdedIQIntegration",
    "ThresholdedIQIntegrationMixed",
    "ThresholdedTriggerCount",
    "Timetag",
    "TimetagTrace",
    "Trace",
    "TriggerCount",
    "TriggerCountDistribution",
    "WeightedIntegratedSeparated",
    "WeightedThresholdedAcquisition",
    # from .operations.conditional_reset
    "ConditionalReset",
    # from .operations.control_flow_library
    "ConditionalOperation",
    "ControlFlowSpec",
    "LoopStrategy",
    # from .operations.control_flow_library (deprecated, resolved via __getattr__)
    "ControlFlowOperation",  # pyright: ignore[reportUnsupportedDunderAll]
    "LoopOperation",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .operations.expressions
    "DType",
    # from .operations.gate_library
    "CNOT",
    "CZ",
    "X90",
    "Y90",
    "Z90",
    "H",
    "Measure",
    "Reset",
    "Rxy",
    "Rz",
    "S",
    "SDagger",
    "T",
    "TDagger",
    "X",
    "Y",
    "Z",
    # from .operations.hardware_operations
    "InlineQ1ASM",
    # from .operations.hardware_operations (deprecated, resolved via __getattr__)
    "long_chirp_pulse",  # pyright: ignore[reportUnsupportedDunderAll]
    "long_ramp_pulse",  # pyright: ignore[reportUnsupportedDunderAll]
    "long_square_pulse",  # pyright: ignore[reportUnsupportedDunderAll]
    "staircase_pulse",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .operations.hardware_operations.pulse_library
    "LatchReset",
    "SimpleNumericalPulse",
    # from .operations.loop_domains
    "arange",
    "linspace",
    # from .operations.nv_native_library
    "ChargeReset",
    "CRCount",
    # from .operations.operation
    "Operation",
    # from .operations.pulse_compensation_library
    "PulseCompensation",
    # from .operations.pulse_library
    "ChirpPulse",
    "DRAGPulse",
    "GaussPulse",
    "IdlePulse",
    "MarkerPulse",
    "NumericalPulse",
    "RampPulse",
    "ReferenceMagnitude",
    "ResetClockPhase",
    "SetClockFrequency",
    "ShiftClockPhase",
    "SkewedHermitePulse",
    "SoftSquarePulse",
    "SquarePulse",
    "StaircasePulse",
    "SuddenNetZeroPulse",
    "Timestamp",
    "VoltageOffset",
    # from .operations.pulse_library (deprecated, resolved via __getattr__)
    "WindowOperation",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .qblox.hardware_agent
    "HardwareAgent",
    # from .resources
    "BasebandClockResource",
    "ClockResource",
    "DigitalClockResource",
    "Resource",
    # from .schedule
    "Schedule",
    # from .schedules.schedule
    "CompiledSchedule",
    "Schedulable",
    # from .schedules.spectroscopy_schedules (deprecated, resolved via __getattr__)
    "heterodyne_spec_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "heterodyne_spec_sched_nco",  # pyright: ignore[reportUnsupportedDunderAll]
    "nv_dark_esr_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "two_tone_spec_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "two_tone_spec_sched_nco",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .schedules.timedomain_schedules (deprecated, resolved via __getattr__)
    "allxy_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "echo_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "rabi_pulse_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "rabi_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "ramsey_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "readout_calibration_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    "t1_sched",  # pyright: ignore[reportUnsupportedDunderAll]
    # from .schedules.trace_schedules (deprecated, resolved via __getattr__)
    "trace_schedule",  # pyright: ignore[reportUnsupportedDunderAll]
    "trace_schedule_circuit_layer",  # pyright: ignore[reportUnsupportedDunderAll]
    "two_tone_trace_schedule",  # pyright: ignore[reportUnsupportedDunderAll]
]