Commit 99afe276 authored by Callum Attryde's avatar Callum Attryde
Browse files

Merge branch 'operation_properties' into 'develop'

Operation properties

Closes #28

See merge request !25
parents 391ac848 dbb3549d
Loading
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -144,8 +144,7 @@ def _add_pulse_information_transmon(schedule, device_cfg: dict):
    validate_config(device_cfg, scheme_fn='transmon_cfg.json')

    for op in schedule.operations.values():
        if 'operation_type' not in op['gate_info'] and len(op['pulse_info']) > 0:
            # this is a pulse operation, make sure the address is resolved
        if op.valid_pulse:
            for pulse in op.data['pulse_info']:
                pulse['channel'] = _walk_address(device_cfg, pulse['channel'])
            continue
+13 −5
Original line number Diff line number Diff line
@@ -187,11 +187,7 @@ class Operation(UserDict):
        super().__init__()

        # ensure keys exist
        self.data['gate_info'] = {
            'unitary': None,
            'tex': '',
            'plot_func': None,
            'qubits': []}
        self.data['gate_info'] = {}
        self.data['pulse_info'] = []  # A list of pulses
        self.data['logic_info'] = {}
        self.modulations = None
@@ -257,6 +253,18 @@ class Operation(UserDict):
        jsonschema.validate(operation.data, scheme)
        return True  # if not exception was raised during validation

    @property
    def valid_gate(self):
        if self.data['gate_info']:
            return True
        return False

    @property
    def valid_pulse(self):
        if self.data['pulse_info']:
            return True
        return False


class Resource(UserDict):
    """
+19 −20
Original line number Diff line number Diff line
@@ -51,8 +51,8 @@ def circuit_diagram_matplotlib(schedule, figsize=None):
    """
    Creates a circuit diagram visualization of a schedule using matplotlib.

    For this visualization backend to work, the schedule must contain `gate_info` for each operation in the
    `operation_dict` as well as a value for `abs_time` for each element in the timing_constraints.
    For this visualization backend to work, the schedule must contain a value for `abs_time` for each element in the
    timing_constraints.

    Parameters
    ----------
@@ -70,8 +70,8 @@ def circuit_diagram_matplotlib(schedule, figsize=None):

    qubits = set()
    for _, op in schedule.operations.items():
        for qubit in op.data['gate_info']['qubits']:
            qubits.add(qubit)
        if op.valid_gate:
            qubits.update(op.data['gate_info']['qubits'])
    qubit_map = {}
    for idx, qubit in enumerate(sorted(qubits)):
        qubit_map[qubit] = idx
@@ -92,22 +92,21 @@ def circuit_diagram_matplotlib(schedule, figsize=None):
    total_duration = 0
    for t_constr in schedule.timing_constraints:
        op = schedule.operations[t_constr['operation_hash']]
        plot_func_name = op['gate_info']['plot_func']

        # todo, hybrid visualisation
        if plot_func_name is None:
            op['gate_info']['plot_func'] = 'quantify.scheduler.visualization.circuit_diagram.gate_box'
            op['gate_info']['tex'] = 'Pulse'
            op['gate_info']['operation_type'] = 'Pulse'
            for pulse in op['pulse_info']:
                op['gate_info']['qubits'].append(pulse['channel'])
        time = t_constr['abs_time']
        total_duration = total_duration if total_duration > time else time

        if op.valid_gate:
            plot_func = import_func_from_string(op['gate_info']['plot_func'])
        # A valid plot_func must accept the following arguments: ax, time (float), qubit_idxs (list), tex (str)
        time = t_constr['abs_time']
            idxs = [qubit_map[q] for q in op['gate_info']['qubits']]
            plot_func(ax, time=time, qubit_idxs=idxs, tex=op['gate_info']['tex'])
        total_duration = total_duration if total_duration > t_constr['abs_time'] else t_constr['abs_time']
    ax.set_xlim(-1, total_duration + 1)
        elif op.valid_pulse:
            plot_func = import_func_from_string('quantify.scheduler.visualization.circuit_diagram.gate_box')
            qubits = [p['channel'] for p in op['pulse_info']]
            idxs = [qubit_map[q] for q in qubits]
            time = t_constr['abs_time']
            plot_func(ax, time=time, qubit_idxs=idxs, tex='Pulse')
        else:
            raise RuntimeError("Unknown operation")

    ax.set_xlim(-1, total_duration + 1)
    return f, ax
+23 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ import pytest
import numpy as np
from quantify.scheduler import Schedule, Operation, Resource
from quantify.scheduler.gate_library import Reset, Measure, CNOT, Rxy, X, X90, Y, Y90, CZ
from quantify.scheduler.pulse_library import SquarePulse
from quantify.scheduler.resources import CompositeResource, Pulsar_QCM_sequencer


@@ -95,3 +96,25 @@ def test_gates_valid():
    assert Operation.is_valid(cz)
    assert Operation.is_valid(cnot)
    assert Operation.is_valid(measure)


def test_type_properties():
    op = Operation('blank op')
    assert not op.valid_gate
    assert not op.valid_pulse

    gate = X('q0')
    assert gate.valid_gate
    assert not gate.valid_pulse

    pulse = SquarePulse(1.0, 20e-9, 'q0')
    assert not pulse.valid_gate
    assert pulse.valid_pulse

    pulse.add_gate_info(X('q0'))
    assert pulse.valid_gate
    assert pulse.valid_pulse

    gate.add_pulse(SquarePulse(1.0, 20e-9, 'q0'))
    assert gate.valid_gate
    assert gate.valid_pulse