Commit fd74defd authored by Kelvin Loh's avatar Kelvin Loh 🖖
Browse files

Merge branch '103-zhinst-backend-debug-mode' into 'develop'

feat(zhinst-backend): Add backend option to enable Calibration mode Closes #103

Closes #103

See merge request !123
parents 364256e3 94b0e80d
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ Unreleased
Merged branches and closed issues
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Feature: Added zhinst backend option to enable Calibration mode, Closes #103. (!123)
* Added acquisitions to circuit diagram (!93)
* Added Chirp and Staircase pulses; and efficient implementation in Qblox backend (!106)

+5 −0
Original line number Diff line number Diff line
@@ -103,6 +103,9 @@ class Device(DataClassJsonMixin):

        For information see zhinst User manuals, section /DEV..../AWGS/n/TIME
        Examples: base sampling rate (1.8 GHz) divided by 2^clock_select. (default = 0)
    mode :
        The Instruments operation mode.
        (default = enums.InstrumentOperationMode.OPERATING)
    device_type :
        The Zurich Instruments hardware type. (default = DeviceType.NONE)
        This field is automatically populated.
@@ -124,6 +127,7 @@ class Device(DataClassJsonMixin):
    channel_3: Optional[Output] = None
    clock_select: Optional[int] = 0
    channelgrouping: int = 0
    mode: enums.InstrumentOperationMode = enums.InstrumentOperationMode.OPERATING
    device_type: DeviceType = DeviceType.NONE
    clock_rate: Optional[int] = field(init=False)
    n_channels: int = field(init=False)
@@ -252,6 +256,7 @@ class InstrumentInfo:
    clock_rate: int
    resolution: int
    granularity: int
    mode: enums.InstrumentOperationMode = enums.InstrumentOperationMode.OPERATING
    low_res_clock: float = field(init=False)

    def __post_init__(self):
+5 −3
Original line number Diff line number Diff line
@@ -207,6 +207,10 @@ def get_wave_instruction(
    )
    n_samples = len(waveform)

    if instrument_info.mode == enums.InstrumentOperationMode.CALIBRATING:
        # Set all the numeric pulse values to one in calibration mode.
        waveform = np.ones(n_samples)

    (
        corrected_start_in_clocks,
        n_samples_shifted,
@@ -596,9 +600,7 @@ def _compile_for_hdawg(
    ValueError
    """
    instrument_info = zhinst.InstrumentInfo(
        device.clock_rate,
        8,
        WAVEFORM_GRANULARITY[device.device_type],
        device.clock_rate, 8, WAVEFORM_GRANULARITY[device.device_type], device.mode
    )
    n_awgs: int = int(device.n_channels / 2)
    settings_builder.with_defaults(
+15 −0
Original line number Diff line number Diff line
@@ -68,3 +68,18 @@ class BinMode(str, Enum):

    APPEND = "append"
    AVERAGE = "average"


@unique
class InstrumentOperationMode(str, Enum):
    """
    The InstrumentOperationMode enum defines in what operational mode an instrument is
    in.

    OPERATING mode sets the Instrument in its default operation mode.
    CALIBRATING mode sets the Instrument in calibration mode in which for example the
    numeric pulses generated by a backend for an AWG are set to np.ones.
    """

    OPERATING = "operate"
    CALIBRATING = "calibrate"
+43 −1
Original line number Diff line number Diff line
@@ -648,7 +648,6 @@ def test__flatten_dict():

def test_get_wave_instruction(mocker, create_schedule_with_pulse_info):
    # Arrange

    q0 = "q0"
    schedule = types.Schedule("test")
    schedule.add(X90(q0))
@@ -680,6 +679,49 @@ def test_get_wave_instruction(mocker, create_schedule_with_pulse_info):
    assert instruction.n_samples_scaled == 9


def test_get_wave_instruction_mode_is_calibrating(
    mocker, create_schedule_with_pulse_info
):
    # Arrange
    q0 = "q0"
    schedule = types.Schedule("test")
    schedule.add(X90(q0))
    schedule = create_schedule_with_pulse_info(schedule)
    schedule = schedule_helpers.CachedSchedule(schedule)

    uuid = next(iter(schedule.pulseid_pulseinfo_dict.keys()))
    output = mocker.create_autospec(zhinst.Output, instance=True)
    instrument_info = zhinst.InstrumentInfo(
        2.4e9, 8, 16, enums.InstrumentOperationMode.CALIBRATING
    )

    def apply_waveform_corrections(  # pylint: disable=unused-argument
        output,
        waveform,
        start_and_duration_in_seconds,
        instrument_info,
        is_pulse,
    ):
        return (start_and_duration_in_seconds[0], len(waveform), waveform)

    mocker.patch.object(
        zhinst_backend,
        "apply_waveform_corrections",
        side_effect=apply_waveform_corrections,
    )

    # Act
    instruction = zhinst_backend.get_wave_instruction(
        uuid, 0, output, schedule, instrument_info
    )

    # Assert
    assert isinstance(instruction, zhinst.Wave)
    np.testing.assert_array_equal(
        instruction.waveform, np.ones(len(instruction.waveform))
    )


def test_get_measure_instruction(mocker, create_schedule_with_pulse_info):
    # Arrange
    q0 = "q0"