def optimize():
    """
    This function optimizes the DC offsets of the quantum controller to minimize the leakage at 7GHz
    :return: Prints the ideal values of the DC offsets and correction matrix variables
    """

    # Connects to the quantum machine through the network
    qmManager = QuantumMachinesManager(host='132.77.48.245')

    # Initial guess for the best offsets
    # Initial guess for correction variables corvars = [0, 1]
    offsets = [-0.08712208, 0.02583852]
    DC_I = offsets[0]
    DC_Q = offsets[1]
    # correction = calc_cmat(corvars[0], corvars[1])

    # Searching parameters, range of parameters for brute force, num of step in the brute force and max iteration fmin
    # OFFSETS
    nstepbruteoffset = 20  # Num of steps in the initial brute force stage(N^2)
    # Range to look in the inital brute force stage
    rangebruteoffset = [(-0.1, 0.1), (-0.1, 0.1)]
    maxiterfminoffset = 100  # maximum number of iteration in the fmin stage

    # CORRECTION VARIABLES
    # Num of steps in the initial brute force stage(N^2)
    nstepbrutecorvars = 20
    # Range to look in the inital brute force stage
    rangebrutecorvars = [(-0.3, 0.3), (0.6, 1.3)]
    maxiterfmincorvars = 100  # maximum number of iteration in the fmin stage

    # Try to initialize the spectrum analyzer
    try:
        # Initializes the instrument
        inst = setinstrument(7e9, 25e5)

    except Exception as e:
        print(
            "An error has occurred trying to initialize the instrument.\nThe Error:\n",
            e)
        exit()

    try:
        # The program that will run on the quantum machine
        with program() as prog:
            with infinite_loop_():
                play('pulse1', 'qe1')

        # The configuration of the quantum program, this is a dictionary, see documentation
        config = setconf(DC_I, DC_Q, correction)

        # Open quantum machine from configuration and force execute it
        qm1 = qmManager.open_qm(config)
        job = qm1.execute(prog, forceExecution=True)

        offsets = brute(power,
                        rangebruteoffset,
                        args=(corvars, qm1, inst, 'offset'),
                        Ns=nstepbruteoffset,
                        finish=None)

        print('\n    Initial guess for the offsets [DC_I, DC_Q]: ', offsets,
              "\n\n")
        # Using fmin function to find the best offsets to minimize the leakage
        xopt = fmin(power,
                    offsets, (corvars, qm1, inst, 'offset'),
                    maxiter=maxiterfminoffset)

    # If there's an error trying to use the "power" function
    except Exception as e:
        print("An error has occurred in the 'power' function. \nThe Error:\n",
              e)
        inst.close()  # Closes the spectrum analyzer
        exit()

    # Redefine the offsets to the values we found
    offsets = xopt
    print("\nOptimal offsets [DC_I, DC_Q]: " + str(offsets) + "\n\n")

    # Define the spectrum analyzer frequency to the left spike frequency
    inst.frequency(7e9 - 25e6)
    try:
        corvars = brute(powerdiffargs,
                        rangebrutecorvars,
                        args=(offsets, qm1, inst),
                        Ns=nstepbrutecorvars,
                        finish=None)
        correction = calc_cmat(corvars[0], corvars[1])
        print("\n    Initial guess from brute force [th, k]: " + str(corvars) +
              "\n\n")

        xopt = fmin(powerdiffargs,
                    corvars, (offsets, qm1, inst),
                    maxiter=maxiterfmincorvars)

    except Exception as e:
        print(
            "An error has occurred trying to find optimal correction matrix.\nThe Error:\n",
            e)
        exit()

    corvars = xopt
    print("\nOptimal correction variables [theta, k]: " + str(corvars))

    inst.close()  # Closes the instrument

    print(
        "\n--------------------------------------------------------------------------------\n\n"
        "Final results: \n"
        "Offsets [DC_I, DC_Q]: " + str(offsets) +
        "\nCorrection variables [theta, k]: " + str(corvars) +
        "\n\n--------------------------------------------------------------------------------\n"
    )
Ejemplo n.º 2
0
from qm.QuantumMachinesManager import QuantumMachinesManager
from qm.qua import *
from qm import SimulationConfig
from configuration import *

# Open communication with the server.
QMm = QuantumMachinesManager()

# Create a quantum machine based on the configuration.
QM1 = QMm.open_qm(config)

with program() as prog:
        play('playOp', 'qe1')

job = QM1.simulate(prog,
                   SimulationConfig(int(300)))

samples = job.get_simulated_samples()

samples.con1.plot()
Ejemplo n.º 3
0
                       int_freq=qubit_IF,
                       mixer=mixer_qubit)
lb_qubit = LabBrick(name="lb_qubit",
                    serial_number=25331,
                    frequency=qubit_LO,
                    power=15)

########################################################################################
########################################################################################

# initialize mixer_rr, rr and the rr's LO
mixer_rr = QuantumElement(
    name="mixer_rr",
    i_offset=rr_mixer_offsets["I"],
    q_offset=rr_mixer_offsets["Q"],
    gain_offset=rr_mixer_offsets["G"],
    phase_offset=rr_mixer_offsets["P"],
)
rr = QuantumElement(name="rr", lo_freq=rr_LO, int_freq=rr_IF, mixer=mixer_rr)
lb_rr = LabBrick(name="lb_rr", serial_number=25335, frequency=rr_LO, power=15)

########################################################################################
########################################################################################

# initialize QM with the updated config file
qmm = QuantumMachinesManager()
qm = qmm.open_qm(config)

########################################################################################
########################################################################################
Ejemplo n.º 4
0
class QuantumMachine(object):
    def __init__(self, connection_info):
        self.connection_info = connection_info

        port = ""
        if self.connection_info[
                "gateway_port"] is not None and self.connection_info[
                    "gateway_port"] != "":
            port = self.connection_info["gateway_port"]

        ip = ""
        if self.connection_info[
                "gateway_ip"] is not None and self.connection_info[
                    "gateway_ip"] != "":
            ip = self.connection_info["gateway_ip"]

        if ip != "" and port != "":
            self.qmm = QuantumMachinesManager(host=ip, port=port)
        else:
            self.qmm = QuantumMachinesManager()

        self.qmObj = None
        self.job = None

    def connect(self):
        """
        Already connected in the constructor
        :return:
        """
        pass

    def connected(self):
        """Return whether or not commands can be sent to the instrument
        """
        try:
            print(self.qmObj.list_controllers())
        except Exception:
            return False

        return True

    def close_connection(self):
        if self.qmObj:
            self.qmObj.close()

    def set_config(self, config):
        self.qmObj = self.qmm.open_qm(config)

    def execute_program(self, prog, duration_limit, data_limit):
        self.job = self.qmObj.execute(prog,
                                      duration_limit=duration_limit,
                                      data_limit=data_limit,
                                      force_execution=True)

    def resume(self):
        self.job.resume()

    def set_output_dc_offset_by_qe(self, element, input, offset):
        self.qmObj.set_output_dc_offset_by_element(element, input, offset)

    def set_input_dc_offset_by_qe(self, element, output, offset):
        self.qmObj.set_input_dc_offset_by_element(element, output, offset)

    def get_results(self):
        return self.job.get_results()

    def set_io_values(self, io1_value, io2_value):
        self.qmObj.set_io_values(io1_value, io2_value)

    def get_io_values(self):
        return self.qmObj.get_io_values()

    def set_mixer_correction(self, mixer, intermediate_frequency, lo_frequency,
                             values):
        self.qmObj.set_mixer_correction(mixer, intermediate_frequency,
                                        lo_frequency, values)

    def set_intermediate_frequency(self, qe, intermediate_frequency):
        self.qmObj.set_intermediate_frequency(qe, intermediate_frequency)

    def set_digital_delay(self, qe, digital_input, delay):
        self.qmObj.set_digital_delay(qe, digital_input, delay)

    def set_digital_buffer(self, qe, digital_input, buffer):
        self.qmObj.set_digital_buffer(qe, digital_input, buffer)
Ejemplo n.º 5
0
class QuantumMachine(BaseInstrument):

    caching_permissions = {}

    def __init__(self,
                 connection_info,
                 caching_allowed=True,
                 caching_permissions={},
                 auto_open=True):
        super(QuantumMachine, self).__init__(connection_info, caching_allowed,
                                             caching_permissions, auto_open)

        self.connection_info = connection_info

        port = ""
        if connection_info[
                "gateway_port"] and connection_info["gateway_port"] != "":
            port = connection_info["gateway_port"]

        ip = ""
        if connection_info[
                "gateway_ip"] and connection_info["gateway_ip"] != "":
            ip = connection_info["gateway_ip"]

        if ip != "" and port != "":
            self.qmm = QuantumMachinesManager(host=ip, port=port)
        else:
            self.qmm = QuantumMachinesManager()

        self.qmObj = None
        self.job = None

    def connect(self):
        """
        Already connected in the constructor
        :return:
        """
        pass

    def connected(self):
        """Return whether or not commands can be sent to the instrument
        """
        try:
            print(self.qmObj.list_controllers())
        except Exception:
            return False

        return True

    def close_connection(self):
        if self.qmObj:
            self.qmObj.close()

    def clear_all_job_results(self):
        self.qmm.clear_all_job_results()

    def set_config(self, config):
        self.qmObj = self.qmm.open_qm(config, close_other_machines=True)

    @requires_config
    def execute_program(self, prog, duration_limit=0, data_limit=0):
        """Create a job on the OPX to execute a program.

        The duration_limit and data_limit arguments specify the
        maximum time and data size that the job can use before getting
        stopped by the server. Those limits are disabled by default.

        """
        self.job = self.qmObj.execute(prog,
                                      duration_limit=duration_limit,
                                      data_limit=data_limit,
                                      force_execution=True)

    @requires_config
    def simulate_program(self, prog, duration):
        """ Simulate the program on the OPX

        The duration parameter specifies the number of FPGA cycles
        of the simulation (4ns/cycle).
        This functions opens a matplotlib popup with the results.
        """
        self.job = self.qmObj.simulate(
            prog,
            SimulationConfig(duration=duration, include_analog_waveforms=True))
        samples = self.job.get_simulated_samples()
        samples.con1.plot(digital_ports=(0, ))
        import matplotlib.pyplot as plt
        plt.show()

    def is_paused(self):
        return self.job.is_paused()

    def resume(self):
        self.job.resume()

    @requires_config
    def set_output_dc_offset_by_qe(self, element, input, offset):
        self.qmObj.set_output_dc_offset_by_element(element, input, offset)

    @requires_config
    def set_input_dc_offset_by_qe(self, element, output, offset):
        self.qmObj.set_input_dc_offset_by_element(element, output, offset)

    @requires_config
    def wait_for_all_results(self, ):
        """Wait for the current job to be completed.
        """
        self.job.result_handles.wait_for_all_values()

    @requires_config
    def get_results(self, path=None):
        return self.job.result_handles

    @requires_config
    def get_execution_report(self, path=None):
        return self.job.execution_report()

    @requires_config
    def set_io_values(self, io1_value, io2_value):
        self.qmObj.set_io_values(io1_value, io2_value)

    @requires_config
    def get_io_values(self):
        return self.qmObj.get_io_values()

    @requires_config
    def set_mixer_correction(self, mixer, intermediate_frequency, lo_frequency,
                             values):
        self.qmObj.set_mixer_correction(mixer, intermediate_frequency,
                                        lo_frequency, values)

    @requires_config
    def set_intermediate_frequency(self, qe, intermediate_frequency):
        self.qmObj.set_intermediate_frequency(qe, intermediate_frequency)

    @requires_config
    def set_digital_delay(self, qe, digital_input, delay):
        self.qmObj.set_digital_delay(qe, digital_input, delay)

    @requires_config
    def set_digital_buffer(self, qe, digital_input, buffer):
        self.qmObj.set_digital_buffer(qe, digital_input, buffer)
Ejemplo n.º 6
0
class QMQubitConfig:
    def __init__(self):

        self.qmm = QuantumMachinesManager()
        self.qm = None

        self.config = None

        # Qubit
        self.qubit_freq = 1e9
        self.QB_IF_freq = 80.0e6
        self.QB_LO_freq = self.qubit_freq - self.QB_IF_freq  # for the mixer

        self.saturation_pulse_len = 50000
        self.pi_pulse_len = 48
        self.pi_wf = pulses.gauss(0.49, 0.0, 10.0, self.pi_pulse_len)
        self.pi2_wf = self.pi_wf / 2

        # Readout
        self.res_freq = 7e9
        self.RR_IF_freq = 62.5e6
        self.RR_LO_up_freq = self.res_freq + self.RR_IF_freq
        self.RR_LO_down_freq = self.res_freq - self.RR_IF_freq

        self.wait_sig = 160  #  minimum 32 clock cycles
        self.smearing_sig = 0  # multiple period
        self.wait_ref = 53  # minimum 32 clock cycles
        self.smearing_ref = 0

        self.readout_pulse_len = 512  # multiple of 16
        self.readout_wf = pulses.const(0.49, self.readout_pulse_len)
        self.theta = 0.0  # rotation of IQ plane

        # create config and load it
        self.load_config()

    def set_readout_wf(self, func, args, plot=False):

        self.readout_wf = func(*args, self.readout_pulse_len)
        self.load_config()

        #if plot:
        #    self.ax.plot(self.readout_wf)
        #    plt.show()

    def set_pi_pulse_wf(self, func, args, plot=False):

        self.pi_wf = func(*args, self.pi_pulse_len)
        self.pi2_wf = self.pi_wf / 2
        self.load_config()

        #if plot:
        #    self.ax.plot(self.pi_wf)
        #    self.ax.plot(self.pi2_wf)
        #    plt.show()

    def set_theta(self, theta):

        self.theta = theta
        self.load_config()

    # TODO set dc offset mixers
    def load_config(self):

        opx_one = "Opx"

        self.config = {
            'version': 1,
            'controllers': {
                opx_one: {
                    'type': 'Opx',
                    'analog_outputs': {
                        # sweep offset of I,Q to see which combination best suppresses LO leakage
                        1: {
                            'offset': 0
                        },  # I qubit
                        2: {
                            'offset': 0
                        },  # Q qubit
                        3: {
                            'offset': 0
                        },  # RR
                    },
                    'analog_inputs': {
                        1: {
                            'offset': 0
                        },  # Reference
                        2: {
                            'offset': 0
                        }  # Signal
                    },
                    'digital_outputs': {
                        1: {}
                    }
                },
            },
            'elements': {
                'signal': {
                    "singleInput": {
                        "port": (opx_one, 3),
                    },
                    'intermediate_frequency': self.RR_IF_freq,
                    'operations': {
                        'readout_sig': 'readout_pulse',
                        'saturation_pulse': 'readout_saturation_pulse',
                    },
                    "outputs": {
                        'out1': (opx_one, 1),
                    },
                    'time_of_flight': 4 * self.wait_sig,
                    'smearing': self.smearing_sig
                },
                'reference': {
                    "singleInput": {
                        "port": (opx_one, 3),
                    },
                    'intermediate_frequency': self.RR_IF_freq,
                    'operations': {
                        'readout_ref': 'reference_pulse',
                    },
                    "outputs": {
                        'out1': (opx_one, 2),  # TODO out2?
                    },
                    'time_of_flight': 4 * self.wait_ref,
                    'smearing': self.smearing_ref
                },
                'qubit': {
                    "mixInputs": {
                        "I": (opx_one, 1),
                        "Q": (opx_one, 2),
                        "mixer": "mixer_QB",
                        "lo_frequency": self.QB_LO_freq
                    },
                    'intermediate_frequency': self.QB_IF_freq,
                    'operations': {
                        'saturation_pulse': 'saturation_pulse',
                        'pi_pulse': 'pi_pulse',
                        'pi/2_pulse': 'pi/2_pulse',
                    }
                },
            },
            "pulses": {
                'readout_saturation_pulse': {
                    'operation': 'control',
                    'length': self.saturation_pulse_len,
                    'waveforms': {
                        'single': 'const_wf',
                    },
                },
                'saturation_pulse': {
                    'operation': 'control',
                    'length': self.saturation_pulse_len,
                    'waveforms': {
                        'I': 'const_wf',
                        'Q': 'zero_wf',
                    }
                },
                'pi_pulse': {
                    'operation': 'control',
                    'length': self.pi_pulse_len,
                    'waveforms': {
                        'I': 'pi_wf',
                        'Q': 'zero_wf'
                    },
                },
                'pi/2_pulse': {
                    'operation': 'control',
                    'length': self.pi_pulse_len,
                    'waveforms': {
                        'I': 'pi/2_wf',
                        'Q': 'zero_wf'
                    },
                },
                'readout_pulse': {
                    'operation': 'measurement',
                    'length': self.readout_pulse_len,
                    'waveforms': {
                        'single': 'readout_wf',
                    },
                    'digital_marker': 'ON',
                    'integration_weights': {
                        'integW_Is': 'integW_Is',
                        'integW_Qs': 'integW_Qs'
                    },
                },
                'reference_pulse': {
                    'operation': 'measurement',
                    'length': self.readout_pulse_len,
                    'waveforms': {
                        'single': 'zero_wf',
                    },
                    'digital_marker': 'ON',
                    'integration_weights': {
                        'integW_Ir': 'integW_Ir',
                        'integW_Qr': 'integW_Qr',
                    }
                },
            },
            'waveforms': {
                'zero_wf': {
                    'type': 'constant',
                    'sample': 0
                },
                'const_wf': {
                    'type': 'constant',
                    'sample': 0.49
                },
                'readout_wf': {
                    'type': 'arbitrary',
                    'samples': self.readout_wf.tolist()
                },
                'pi_wf': {
                    'type': 'arbitrary',
                    'samples': self.pi_wf.tolist()
                },
                'pi/2_wf': {
                    'type': 'arbitrary',
                    'samples': self.pi2_wf.tolist()
                }
            },
            'digital_waveforms': {
                'ON': {
                    'samples': [(1, 0)]
                },
            },
            'integration_weights': {
                'integW_Is': {
                    'cosine': [np.cos(self.theta / 360 * np.pi)] *
                    int(self.readout_pulse_len / 4 + self.smearing_sig),
                    'sine': [np.sin(self.theta / 360 * np.pi)] *
                    int(self.readout_pulse_len / 4 + self.smearing_sig),
                },
                'integW_Qs': {
                    'cosine': [np.sin(-self.theta / 360 * np.pi)] *
                    int(self.readout_pulse_len / 4 + self.smearing_sig),
                    'sine': [np.cos(self.theta / 360 * np.pi)] *
                    int(self.readout_pulse_len / 4 + self.smearing_sig),
                },
                'integW_Ir': {
                    'cosine': [np.cos(self.theta / 360 * np.pi)] *
                    int(self.readout_pulse_len / 4 + self.smearing_ref),
                    'sine': [np.sin(-self.theta / 360 * np.pi)] *
                    int(self.readout_pulse_len / 4 + self.smearing_ref),
                },
                'integW_Qr': {
                    'cosine': [np.sin(self.theta / 360 * np.pi)] *
                    int(self.readout_pulse_len / 4 + self.smearing_ref),
                    'sine': [np.cos(self.theta / 360 * np.pi)] *
                    int(self.readout_pulse_len / 4 + self.smearing_ref),
                },
            },
            'mixers': {
                'mixer_QB': [{
                    'intermediate_frequency': self.QB_IF_freq,
                    'lo_frequency': self.QB_LO_freq,
                    'correction': [1, 0, 0, 1]
                }],
            },
        }

        self.qm = self.qmm.open_qm(self.config)

    # TODO make it nice
    def print_config(self):
        print(self.config)