def four_qubit_off_on(
    q0_pulse_pars, q1_pulse_pars, q2_pulse_pars, q3_pulse_pars, RO_pars, return_seq=False, verbose=False
):

    seq_name = "4_qubit_OffOn_sequence"
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    # Create a dict with the parameters for all the pulses
    q0_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q0_pulse_pars), " q0")
    q1_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q1_pulse_pars), " q1")
    q2_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q2_pulse_pars), " q2")
    q3_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q3_pulse_pars), " q3")
    RO_dict = {"RO": RO_pars}

    pulse_dict = {}
    pulse_dict.update(q0_pulses)
    pulse_dict.update(q1_pulses)
    pulse_dict.update(q2_pulses)
    pulse_dict.update(q3_pulses)
    pulse_dict.update(RO_dict)

    # N.B. Identities not needed in all cases
    pulse_combinations = [
        ["I q0", "I q1", "I q2", "I q3", "RO"],
        ["X180 q0", "I q1", "I q2", "I q3", "RO"],
        ["I q0", "X180 q1", "I q2", "I q3", "RO"],
        ["X180 q0", "X180 q1", "I q2", "I q3", "RO"],
        ["I q0", "I q1", "X180 q2", "I q3", "RO"],
        ["X180 q0", "I q1", "X180 q2", "I q3", "RO"],
        ["I q0", "X180 q1", "X180 q2", "I q3", "RO"],
        ["X180 q0", "X180 q1", "X180 q2", "I q3", "RO"],
        ["I q0", "I q1", "I q2", "X180 q3", "RO"],
        ["X180 q0", "I q1", "I q2", "X180 q3", "RO"],
        ["I q0", "X180 q1", "I q2", "X180 q3", "RO"],
        ["X180 q0", "X180 q1", "I q2", "X180 q3", "RO"],
        ["I q0", "I q1", "X180 q2", "X180 q3", "RO"],
        ["X180 q0", "I q1", "X180 q2", "X180 q3", "RO"],
        ["I q0", "X180 q1", "X180 q2", "X180 q3", "RO"],
        ["X180 q0", "X180 q1", "X180 q2", "X180 q3", "RO"],
    ]

    for i, pulse_comb in enumerate(pulse_combinations):
        pulses = []
        for p in pulse_comb:
            pulses += [pulse_dict[p]]

        el = multi_pulse_elt(i, station, pulses)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)
    station.components["AWG"].stop()
    station.pulsar.program_awg(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq_name
def GST_from_textfile(pulse_pars, RO_pars, filename,
                      upload=True, seq_name=None,
                      verbose=False):
    '''
    Input pars:
        pulse_pars:     dict containing the pulse parameters
        RO_pars:        dict containing the RO parameters
        filename:       name of a pygsti generated text file
        upload:         upload to AWG or not, if returns seq, el_list
    '''
    if seq_name is None:
        seq_name = 'GST_seq'
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    # Create a dict with the parameters for all the pulses
    pulse_dict = get_pulse_dict_from_pars(pulse_pars)
    pulse_dict['RO'] = RO_pars
    pulse_combinations = create_experiment_list_pyGSTi_general(filename)
    for i, pulse_comb in enumerate(pulse_combinations):
        pulse_list = []
        for pulse_key in pulse_comb:
            pulse_list += [pulse_dict[pulse_key]]
        el = multi_pulse_elt(i, station, pulse_list)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    if upload:
        station.components['AWG'].stop()
        station.pulsar.program_awg(seq, *el_list, verbose=verbose)
    return seq, el_list
def Ramsey_2nd_exc_seq(times, pulse_pars, pulse_pars_2nd, RO_pars, n=1,
                     cal_points=True,
                     post_msmt_delay=3e-6, verbose=False):
    '''
    Rabi sequence for the second excited state
    Input pars:
        amps:            array of pulse amplitudes (V)
        pulse_pars:      dict containing the pulse parameters
        pulse_pars_2nd:  dict containing pulse_parameters for 2nd exc. state
        RO_pars:         dict containing the RO parameters
        n:               number of pulses (1 is conventional Rabi)
        post_msmt_delay: extra wait time for resetless compatibility
    '''
    seq_name = 'Ramsey_2nd_exc_sequence'
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    pulses = get_pulse_dict_from_pars(pulse_pars)
    pulses_2nd = get_pulse_dict_from_pars(pulse_pars_2nd)
    for i, tau in enumerate(times):
        if cal_points and (i == (len(times)-6) or
                           i == (len(times)-5)):
            el = multi_pulse_elt(i, station, [pulses['I'], RO_pars])
        elif cal_points and (i == (len(times)-4) or
                             i == (len(times)-3)):
            el = multi_pulse_elt(i, station, [pulses['X180'], RO_pars])
        elif cal_points and (i == (len(times)-2) or
                             i == (len(times)-1)):
            el = multi_pulse_elt(i, station, [pulses['X180'], pulses['X180'],
                                 RO_pars])
        else:
            pulse_pars_x2 = deepcopy(pulses_2nd['X90'])
            pulse_pars_x2['pulse_delay'] = tau

            pulse_list = ([pulses['X180']]+n*[pulses_2nd['X90'], pulse_pars_x2] +
                          [pulses['X180'], RO_pars])

            # copy first element and set extra wait
            pulse_list[0] = deepcopy(pulse_list[0])
            pulse_list[0]['pulse_delay'] += post_msmt_delay
            el = multi_pulse_elt(i, station, pulse_list)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)
    station.components['AWG'].stop()
    station.pulsar.program_awg(seq, *el_list, verbose=verbose)
    return seq_name
Exemplo n.º 4
0
def SSRO_2nd_exc_state(pulse_pars, pulse_pars_2nd, RO_pars, verbose=False):

    seq_name = 'SSRO_2nd_exc'
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    pulses = get_pulse_dict_from_pars(pulse_pars)
    pulses_2nd = get_pulse_dict_from_pars(pulse_pars_2nd)
    # First element

    pulse_combinations = [[pulses['I']] + [RO_pars]]
    pulse_combinations += [[pulses['X180']] + [RO_pars]]
    pulse_combinations += [[pulses['X180']] + [pulses_2nd['X180']] + [RO_pars]]

    for i, pulse_list in enumerate(pulse_combinations):
        el = multi_pulse_elt(i, station, pulse_list)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)
    seq.append_element(el, trigger_wait=True)
    station.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    return seq_name
def SSRO_2nd_exc_state(pulse_pars, pulse_pars_2nd, RO_pars, verbose=False):

    seq_name = 'SSRO_2nd_exc'
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    pulses = get_pulse_dict_from_pars(pulse_pars)
    pulses_2nd = get_pulse_dict_from_pars(pulse_pars_2nd)
    # First element

    pulse_combinations = [[pulses['I']]+[RO_pars]]
    pulse_combinations += [[pulses['X180']] +[RO_pars]]
    pulse_combinations += [[pulses['X180']]+[pulses_2nd['X180']] +[RO_pars]]

    for i, pulse_list in enumerate(pulse_combinations):
        el = multi_pulse_elt(i, station, pulse_list)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)
    seq.append_element(el, trigger_wait=True)
    station.components['AWG'].stop()
    station.pulsar.program_awg(seq, *el_list, verbose=verbose)
    return seq_name
def two_qubit_off_on(q0_pulse_pars, q1_pulse_pars, RO_pars,
                     return_seq=False, verbose=False):

    seq_name = '2_qubit_OffOn_sequence'
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    # Create a dict with the parameters for all the pulses
    q0_pulses = add_suffix_to_dict_keys(
        get_pulse_dict_from_pars(q0_pulse_pars), ' q0')
    q1_pulses = add_suffix_to_dict_keys(
        get_pulse_dict_from_pars(q1_pulse_pars), ' q1')
    RO_dict = {'RO': RO_pars}

    pulse_dict = {}
    pulse_dict.update(q0_pulses)
    pulse_dict.update(q1_pulses)
    pulse_dict.update(RO_dict)

    # N.B. Identities not needed in all cases
    pulse_combinations = [['I q0', 'I q1', 'RO'],
                          ['X180 q0', 'I q1', 'RO'],
                          ['I q0', 'X180 q1', 'RO'],
                          ['X180 q0', 'X180 q1', 'RO']]

    for i, pulse_comb in enumerate(pulse_combinations):
        pulses = []
        for p in pulse_comb:
            pulses += [pulse_dict[p]]

        el = multi_pulse_elt(i, station, pulses)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)
    station.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq_name
def n_qubit_off_on(pulse_pars_list, RO_pars, return_seq=False, verbose=False,
                   parallel_pulses=False, preselection=False,
                   RO_spacing=200e-9):
    n = len(pulse_pars_list)
    seq_name = '{}_qubit_OffOn_sequence'.format(n)
    seq = sequence.Sequence(seq_name)
    el_list = []

    # Create a dict with the parameters for all the pulses
    pulse_dict = {'RO': RO_pars}
    for i, pulse_pars in enumerate(pulse_pars_list):
        pars = pulse_pars.copy()
        if i != 0 and parallel_pulses:
            pars['refpoint'] = 'start'
        pulses = add_suffix_to_dict_keys(
            get_pulse_dict_from_pars(pars), ' {}'.format(i))
        pulse_dict.update(pulses)
    spacerpulse = {'pulse_type': 'SquarePulse',
                   'channel': RO_pars['acq_marker_channel'],
                   'amplitude': 0.0,
                   'length': RO_spacing,
                   'pulse_delay': 0}
    pulse_dict.update({'spacer': spacerpulse})

    # Create a list of required pulses
    pulse_combinations = []
    for pulse_list in itertools.product(*(n*[['I', 'X180']])):
        pulse_comb = (n+1)*['']
        for i, pulse in enumerate(pulse_list):
            pulse_comb[i] = pulse + ' {}'.format(i)
        pulse_comb[-1] = 'RO'
        if preselection:
            pulse_comb = ['RO', 'spacer'] + pulse_comb
        pulse_combinations.append(pulse_comb)

    for i, pulse_comb in enumerate(pulse_combinations):
        pulses = []
        for j, p in enumerate(pulse_comb):
            pulses += [pulse_dict[p]]
        el = multi_pulse_elt(i, station, pulses)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)
    station.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq_name
    def get_pulse_dict(self, pulse_dict={}):
        '''
        Returns a dictionary containing the pulse parameters of the qubit.
        This function is intended to replace the old get_pulse_pars.
        Dictionary contains the keys formatted as follows:
            operation self.name

        Input args:
            pulse_dict (dict):  Optionally specify an existing pulse dict to update

        (currently only contains single qubit pulses)
        '''
        drive_pars, RO_pars = self.get_pulse_pars()
        pulse_dict.update(add_suffix_to_dict_keys(
            sq.get_pulse_dict_from_pars(drive_pars), ' ' + self.name))
        pulse_dict.update({'RO {}'.format(self.name): RO_pars})

        spec_pars, RO_pars = self.get_spec_pars()
        pulse_dict.update({'Spec {}'.format(self.name): spec_pars})

        return pulse_dict
def capacity_tomo_seq(bases, states, idle_time, pulse_pars, RO_pars,
                      upload=True,
                      verbose=False):
    """
    input pars
        bases list of ints:
            0 - Z-basis
            1 - X-basis
            2 - Y-basis
        states (list of ints):
            0 - |0>
            1 - |1>
        idle_time (s)


    """
    assert(len(bases) == len(states))
    seq_name = 'Capacity_tomo_seq'
    seq = sequence.Sequence(seq_name)
    el_list = []
    # Create a dict with the parameters for all the pulses
    pulse_dict = get_pulse_dict_from_pars(pulse_pars)
    pulse_dict['I']['pulse_delay'] = idle_time
    pulse_dict['RO'] = RO_pars

    pulse_combinations = [['I', 'RO'],
                          ['X180', 'I', 'RO'],
                          ['Y90', 'I', 'mY90', 'RO'],
                          ['mY90', 'I', 'mY90', 'RO'],
                          ['X90', 'I', 'mX90', 'RO'],
                          ['mX90', 'I', 'mX90', 'RO']]
    # Creates elements containing the primitive pulse sequences
    for i, pulse_comb in enumerate(pulse_combinations):
        pulse_list = []
        for pulse_key in pulse_comb:
            pulse_list += [pulse_dict[pulse_key]]
        el = multi_pulse_elt(i, station, pulse_list)
        el_list.append(el)

    seq_idx = []
    # Selects the corresponding pulse combination
    for basis, state in zip(bases, states):
        if state not in [0, 1]:
            raise ValueError('state {} not recognized'.format(state))
        if basis == 0:  # computational(Z)-basis
            if state == 0:
                seq_idx += [0]
            elif state == 1:
                seq_idx += [1]
        elif basis == 1:  # X basis
            if state == 0:
                seq_idx += [2]
            if state == 1:
                seq_idx += [3]
        elif basis == 2:  # Y basis
            if state == 0:
                seq_idx += [4]
            if state == 1:
                seq_idx += [5]
        else:
            raise ValueError('basis {} not recognized'.formate(basis))
    # Creates a sequence by selecting the right primitive element
    for i, idx in enumerate(seq_idx):
        seq.append(name='elt_{}'.format(i),
                   wfname=el_list[idx].name, trigger_wait=True)
    if upload:
        station.components['AWG'].stop()
        station.pulsar.program_awg(seq, *el_list, verbose=verbose)
    return seq, el_list
def cphase_fringes(phases, q0_pulse_pars, q1_pulse_pars, RO_pars,
                   swap_pars_q0, cphase_pars_q1, timings_dict,
                   distortion_dict, verbose=False, upload=True, return_seq=False):
    '''
    '''
    preloaded_kernels_vec = preload_kernels_func(distortion_dict)
    original_delay = deepcopy(RO_pars)[0]['pulse_delay']
    seq_name = 'CPhase'
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    # print(q0_pulse_pars)
    q0_pulses = add_suffix_to_dict_keys(
        get_pulse_dict_from_pars(q0_pulse_pars[0]), ' q0')
    q1_pulses = add_suffix_to_dict_keys(
        get_pulse_dict_from_pars(q1_pulse_pars[0]), ' q1')

    pulse_dict = {}
    pulse_dict.update(q0_pulses)
    pulse_dict.update(q1_pulses)
    pulse_dict.update({'RO': RO_pars[0]})
    # print({'RO': RO_pars})

    # Timings
    buffer_mw_flux = timings_dict[0]['buffer_mw_flux']
    buffer_flux_mw = timings_dict[0]['buffer_flux_mw']
    msmt_buffer = timings_dict[0]['msmt_buffer']
    dead_time = timings_dict[0]['dead_time']
    # print(buffer_mw_flux,buffer_flux_mw,msmt_buffer,dead_time)

    # defining main pulses
    exc_pulse = deepcopy(pulse_dict['X180 q0'])
    exc_pulse['pulse_delay'] += 0.01e-6
    swap_pulse_1 = deepcopy(swap_pars_q0[0])
    # print(swap_pulse_1)
    swap_pulse_1['pulse_delay'] = buffer_mw_flux + \
        exc_pulse['sigma']*exc_pulse['nr_sigma']

    ramsey_1 = deepcopy(pulse_dict['Y90 q1'])
    ramsey_1['pulse_delay'] = buffer_flux_mw + swap_pulse_1['length']
    cphase_pulse = cphase_pars_q1[0]
    cphase_amp = cphase_pulse['amplitude']
    cphase_pulse['pulse_delay'] = buffer_mw_flux + \
        ramsey_1['sigma']*ramsey_1['nr_sigma']
    ramsey_2 = deepcopy(pulse_dict['X90 q1'])
    ramsey_2['pulse_delay'] = buffer_flux_mw + cphase_pulse['length']

    swap_pulse_2 = deepcopy(swap_pars_q0[0])
    swap_pulse_2['pulse_delay'] = buffer_mw_flux + \
        ramsey_2['sigma']*ramsey_2['nr_sigma']
    RO_pars[0]['pulse_delay'] = msmt_buffer + swap_pulse_2['length']

    # defining compensation pulses
    swap_comp_1 = deepcopy(swap_pulse_1)
    swap_pulse_1['pulse_delay'] = RO_pars[0]['length'] + dead_time
    cphase_comp = deepcopy(cphase_pulse)
    swap_comp_2 = deepcopy(swap_pulse_2)

    dead_time_pulse = {'pulse_type': 'SquarePulse',
                       'pulse_delay': RO_pars[0]['pulse_delay'],
                       'channel': swap_pars_q0[0]['channel'],
                       'amplitude': 0,
                       'length': dead_time}

    for i, ph2 in enumerate(phases[0]):
        # print(ph2)
        ramsey_2['phase'] = ph2

        cphase_pulse['amplitude'] = cphase_amp
        pulse_list = [exc_pulse,
                      swap_pulse_1,
                      ramsey_1,
                      cphase_pulse,
                      ramsey_2,
                      swap_pulse_2,
                      RO_pars[0],
                      swap_comp_1,
                      cphase_comp,
                      swap_comp_2,
                      dead_time_pulse]
        el = multi_pulse_elt(2*i, station, pulse_list)
        el_list.append(el)

        cphase_pulse['amplitude'] = 0.
        pulse_list = [exc_pulse,
                      swap_pulse_1,
                      ramsey_1,
                      cphase_pulse,
                      ramsey_2,
                      swap_pulse_2,
                      RO_pars[0],
                      swap_comp_1,
                      cphase_comp,
                      swap_comp_2,
                      dead_time_pulse]
        el = multi_pulse_elt(2*i+1, station, pulse_list)
        el_list.append(el)

    # Compensations
    for i, el in enumerate(el_list):
        if distortion_dict is not None:
            el = distort_and_compensate(
                el, distortion_dict, preloaded_kernels_vec)
            el_list[i] = el
        seq.append_element(el, trigger_wait=True)
    cal_points = 4
    RO_pars[0]['pulse_delay'] = original_delay

    # Calibration points
    cal_points = [['I q0', 'I q1', 'RO'],
                  ['I q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO']]

    for i, pulse_comb in enumerate(cal_points):
        pulses = []
        for p in pulse_comb:
            pulses += [pulse_dict[p]]
        pulses[0]['pulse_delay'] += 0.01e-6

        el = multi_pulse_elt(2*len(phases)+i, station, pulses)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    # upload
    if upload:
        station.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq
def two_qubit_tomo_cardinal(cardinal,
                            q0_pulse_pars,
                            q1_pulse_pars,
                            RO_pars,
                            timings_dict,
                            verbose=False,
                            upload=True,
                            return_seq=False):

    seq_name = '2_qubit_Card_%d_seq' % cardinal
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    # Create a dict with the parameters for all the pulses
    q0_pulses = add_suffix_to_dict_keys(
        get_pulse_dict_from_pars(q0_pulse_pars), ' q0')
    q1_pulses = add_suffix_to_dict_keys(
        get_pulse_dict_from_pars(q1_pulse_pars), ' q1')
    RO_dict = {'RO': RO_pars}

    pulse_dict = {}
    pulse_dict.update(q0_pulses)
    pulse_dict.update(q1_pulses)
    pulse_dict.update(RO_dict)

    # Timings
    # FIXME: This dictionary should not be required? -MAR
    # NOTE: required in the CPhase tomo as input but not used
    QQ_buffer = timings_dict['QQ_buffer']
    wait_time = timings_dict['wait_time']
    msmt_buffer = timings_dict['msmt_buffer']

    tomo_list_q0 = ['I q0', 'X180 q0', 'Y90 q0',
                    'mY90 q0', 'X90 q0', 'mX90 q0']
    tomo_list_q1 = ['I q1', 'X180 q1', 'Y90 q1',
                    'mY90 q1', 'X90 q1', 'mX90 q1']

    # inner loop on q0
    prep_idx_q0 = int(cardinal % 6)
    prep_idx_q1 = int(((cardinal - prep_idx_q0)/6) % 6)

    prep_pulse_q0 = pulse_dict[tomo_list_q0[prep_idx_q0]]
    prep_pulse_q1 = pulse_dict[tomo_list_q1[prep_idx_q1]]

    prep_pulse_q1['pulse_delay'] = QQ_buffer + (prep_pulse_q0['sigma'] *
                                                prep_pulse_q0['nr_sigma'])

    RO_pars['pulse_delay'] += msmt_buffer - (prep_pulse_q1['sigma'] *
                                             prep_pulse_q1['nr_sigma'])

    # Calibration points
    cal_points = [['I q0', 'I q1', 'RO'],
                  ['I q0', 'I q1', 'RO'],
                  ['I q0', 'I q1', 'RO'],
                  ['I q0', 'I q1', 'RO'],
                  ['I q0', 'I q1', 'RO'],
                  ['I q0', 'I q1', 'RO'],
                  ['I q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['X180 q0', 'I q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['I q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO'],
                  ['X180 q0', 'X180 q1', 'RO']]

    for i in range(36):
        tomo_idx_q0 = int(i % 6)
        tomo_idx_q1 = int(((i - tomo_idx_q0)/6) % 6)

        # print(i,tomo_idx_q0,tomo_idx_q1)

        tomo_pulse_q0 = pulse_dict[tomo_list_q0[tomo_idx_q0]]
        tomo_pulse_q1 = pulse_dict[tomo_list_q1[tomo_idx_q1]]

        tomo_pulse_q0['pulse_delay'] = wait_time + (prep_pulse_q1['sigma'] *
                                                    prep_pulse_q1['nr_sigma'])

        tomo_pulse_q1['pulse_delay'] = QQ_buffer + (tomo_pulse_q0['sigma'] *
                                                    tomo_pulse_q0['nr_sigma'])
        pulse_list = [prep_pulse_q0,
                      prep_pulse_q1,
                      tomo_pulse_q0,
                      tomo_pulse_q1,
                      RO_pars]
        el = multi_pulse_elt(i, station, pulse_list)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    for i, pulse_comb in enumerate(cal_points):
        pulses = []
        for p in pulse_comb:
            pulses += [pulse_dict[p]]

        el = multi_pulse_elt(35+i, station, pulses)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    station.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq_name
def two_qubit_tomo_cardinal(
    cardinal, q0_pulse_pars, q1_pulse_pars, RO_pars, timings_dict, verbose=False, upload=True, return_seq=False
):

    seq_name = "2_qubit_Card_%d_seq" % cardinal
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    # Create a dict with the parameters for all the pulses
    q0_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q0_pulse_pars), " q0")
    q1_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q1_pulse_pars), " q1")
    RO_dict = {"RO": RO_pars}

    pulse_dict = {}
    pulse_dict.update(q0_pulses)
    pulse_dict.update(q1_pulses)
    pulse_dict.update(RO_dict)

    # Timings
    QQ_buffer = timings_dict["QQ_buffer"]
    wait_time = timings_dict["wait_time"]
    msmt_buffer = timings_dict["msmt_buffer"]

    tomo_list_q0 = ["I q0", "X180 q0", "Y90 q0", "mY90 q0", "X90 q0", "mX90 q0"]
    tomo_list_q1 = ["I q1", "X180 q1", "Y90 q1", "mY90 q1", "X90 q1", "mX90 q1"]

    # inner loop on q0
    prep_idx_q0 = int(cardinal % 6)
    prep_idx_q1 = int(((cardinal - prep_idx_q0) / 6) % 6)

    prep_pulse_q0 = pulse_dict[tomo_list_q0[prep_idx_q0]]
    prep_pulse_q1 = pulse_dict[tomo_list_q1[prep_idx_q1]]

    prep_pulse_q1["pulse_delay"] = QQ_buffer + (prep_pulse_q0["sigma"] * prep_pulse_q0["nr_sigma"])

    RO_pars["pulse_delay"] += msmt_buffer - (prep_pulse_q1["sigma"] * prep_pulse_q1["nr_sigma"])

    # Calibration points
    cal_points = [
        ["I q0", "I q1", "RO"],
        ["I q0", "I q1", "RO"],
        ["I q0", "I q1", "RO"],
        ["I q0", "I q1", "RO"],
        ["I q0", "I q1", "RO"],
        ["I q0", "I q1", "RO"],
        ["I q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
    ]

    for i in range(36):
        tomo_idx_q0 = int(i % 6)
        tomo_idx_q1 = int(((i - tomo_idx_q0) / 6) % 6)

        # print(i,tomo_idx_q0,tomo_idx_q1)

        tomo_pulse_q0 = pulse_dict[tomo_list_q0[tomo_idx_q0]]
        tomo_pulse_q1 = pulse_dict[tomo_list_q1[tomo_idx_q1]]

        tomo_pulse_q0["pulse_delay"] = wait_time + (prep_pulse_q1["sigma"] * prep_pulse_q1["nr_sigma"])

        tomo_pulse_q1["pulse_delay"] = QQ_buffer + (tomo_pulse_q0["sigma"] * tomo_pulse_q0["nr_sigma"])
        pulse_list = [prep_pulse_q0, prep_pulse_q1, tomo_pulse_q0, tomo_pulse_q1, RO_pars]
        pulse_list[0]["pulse_delay"] += 0.01e-6
        el = multi_pulse_elt(i, station, pulse_list)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    for i, pulse_comb in enumerate(cal_points):
        pulses = []
        for p in pulse_comb:
            pulses += [pulse_dict[p]]
        pulses[0]["pulse_delay"] += 0.01e-6

        el = multi_pulse_elt(35 + i, station, pulses)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    station.components["AWG"].stop()
    station.pulsar.program_awg(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq_name
def two_qubit_AllXY(
    q0_pulse_pars, q1_pulse_pars, RO_pars, double_points=True, verbose=False, upload=True, return_seq=False
):
    """
    Performs an AllXY on the first qubit will doing a pi-pulse before
    and after the AllXY on the second qubit
    AllXY q0 - RO
    X180 q1 - AllXY q0 - X180 q1 - RO
    """
    seq_name = "2_qubit_AllXY_sequence"
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    # Create a dict with the parameters for all the pulses
    q0_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q0_pulse_pars), " q0")
    q1_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q1_pulse_pars), " q1")
    RO_dict = {"RO": RO_pars}

    pulse_dict = {}
    pulse_dict.update(q0_pulses)
    pulse_dict.update(q1_pulses)
    pulse_dict.update(RO_dict)
    AllXY_pulse_combinations = [
        ["I q0", "I q0"],
        ["X180 q0", "X180 q0"],
        ["Y180 q0", "Y180 q0"],
        ["X180 q0", "Y180 q0"],
        ["Y180 q0", "X180 q0"],
        ["X90 q0", "I q0"],
        ["Y90 q0", "I q0"],
        ["X90 q0", "Y90 q0"],
        ["Y90 q0", "X90 q0"],
        ["X90 q0", "Y180 q0"],
        ["Y90 q0", "X180 q0"],
        ["X180 q0", "Y90 q0"],
        ["Y180 q0", "X90 q0"],
        ["X90 q0", "X180 q0"],
        ["X180 q0", "X90 q0"],
        ["Y90 q0", "Y180 q0"],
        ["Y180 q0", "Y90 q0"],
        ["X180 q0", "I q0"],
        ["Y180 q0", "I q0"],
        ["X90 q0", "X90 q0"],
        ["Y90 q0", "Y90 q0"],
    ]

    if double_points:
        AllXY_pulse_combinations = [val for val in AllXY_pulse_combinations for _ in (0, 1)]
    pulse_list = []
    for pulse_comb in AllXY_pulse_combinations:
        pulse_list += [pulse_comb + ["RO"]]
    for pulse_comb in AllXY_pulse_combinations:
        pulse_list += [["X180 q1"] + pulse_comb + ["X180 q1", "RO"]]
    for i, pulse_comb in enumerate(pulse_list):
        pulses = []
        for p in pulse_comb:
            pulses += [pulse_dict[p]]
        el = multi_pulse_elt(i, station, pulses)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    station.components["AWG"].stop()
    station.pulsar.program_awg(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq_name
def echo_2nd_exc_seq(times, pulse_pars, pulse_pars_2nd, RO_pars,
                     cal_points=True, no_cal_points=6, artificial_detuning=None,
                     verbose=False, upload=True, return_seq=False,
                     last_ge_pulse=True):
    raise NotImplementedError(
        'echo_2nd_exc_seq has not been '
        'converted to the latest waveform generation code and can not be used.')

    seq_name = 'Echo_2nd_exc_sequence'
    seq = sequence.Sequence(seq_name)
    el_list = []
    pulses = get_pulse_dict_from_pars(pulse_pars)
    pulses_2nd = get_pulse_dict_from_pars(pulse_pars_2nd)

    center_X180ef = deepcopy(pulses_2nd['X180'])
    final_X90ef = deepcopy(pulses_2nd['X90'])
    center_X180ef['ref_point'] = 'start'
    final_X90ef['ref_point'] = 'start'

    for i, tau in enumerate(times):
        center_X180ef['pulse_delay'] = tau/2
        final_X90ef['pulse_delay'] = tau/2
        if artificial_detuning is not None:
            final_X90ef['phase'] = (tau-times[0]) * artificial_detuning * 360

        if cal_points and no_cal_points == 6 and \
                (i == (len(times)-6) or i == (len(times)-5)):
            el = multi_pulse_elt(i, station, [pulses['I'], pulses_2nd['I'],
                                              RO_pars])
        elif cal_points and no_cal_points == 6 and \
                (i == (len(times)-4) or i == (len(times)-3)):
            el = multi_pulse_elt(i, station, [pulses['X180'], pulses_2nd['I'],
                                              RO_pars])
        elif cal_points and no_cal_points == 6 and \
                (i == (len(times)-2) or i == (len(times)-1)):
            el = multi_pulse_elt(i, station, [pulses['X180'],
                                              pulses_2nd['X180'],
                                              RO_pars])
        elif cal_points and no_cal_points == 4 and \
                (i == (len(times)-4) or i == (len(times)-3)):
            el = multi_pulse_elt(i, station, [pulses['I'], pulses_2nd['I'],
                                              RO_pars])
        elif cal_points and no_cal_points == 4 and \
                (i == (len(times)-2) or i == (len(times)-1)):
            el = multi_pulse_elt(i, station, [pulses['X180'], pulses_2nd['I'],
                                              RO_pars])
        elif cal_points and no_cal_points == 2 and \
                (i == (len(times)-2) or i == (len(times)-1)):
            el = multi_pulse_elt(i, station, [pulses['I'], pulses_2nd['I'],
                                              RO_pars])
        else:
            pulse_list = [pulses['X180'], pulses_2nd['X90'],
                          center_X180ef, final_X90ef]
            if last_ge_pulse:
                pulse_list += [pulses['X180']]
            pulse_list += [RO_pars]
            el = multi_pulse_elt(i, station, pulse_list)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    if upload:
        station.pulsar.program_awgs(seq, *el_list, verbose=verbose)

    if return_seq:
            return seq_name, el_list
    else:
        return seq
Exemplo n.º 15
0
def readout_pulse_scope_seq(delays,
                            pulse_pars,
                            RO_pars,
                            RO_separation,
                            cal_points=((-4, -3), (-2, -1)),
                            comm_freq=225e6,
                            upload=True,
                            return_seq=False,
                            prep_pulses=None,
                            verbose=False):
    """
    Prepares the AWGs for a readout pulse shape and timing measurement.

    The sequence consists of two readout pulses where the drive pulse start
    time is swept through the first readout pulse. Because the photons in the
    readout resonator induce an ac-Stark shift of the qubit frequency, we can
    determine the readout pulse shape by sweeping the drive frequency in an
    outer loop to determine the qubit frequency.

    Important: This sequence includes two readouts per segment. For this reason
    the calibration points are also duplicated.

    Args:
        delays: A list of delays between the start of the first readout pulse
                and the end of the drive pulse.
        pulse_pars: Pulse dictionary for the drive pulse.
        RO_pars: Pulse dictionary for the readout pulse.
        RO_separation: Separation between the starts of the two readout pulses.
                       If the comm_freq parameter is not None, the used value
                       is increased to satisfy the commensurability constraint.
        cal_points: True for default calibration points, False for no
                          calibration points or a list of two lists, containing
                          the indices of the calibration segments for the ground
                          and excited state.
        comm_freq: The readout pulse separation will be a multiple of
                   1/comm_freq
    Returns:
        The sequence object and the element list if return_seq is True. Else
        return the sequence name.
    """
    if cal_points:
        cal_points = ((-4, -3), (-2, -1))
    elif not cal_points or cal_points is None:
        cal_points = ((), ())
    if prep_pulses is None:
        prep_pulses = []
    if comm_freq:
        RO_separation -= RO_separation % (-1 / comm_freq)

    seq_name = 'readout_pulse_scope_sequence'
    seq = sequence.Sequence(seq_name)
    seg_list = []
    pulses = get_pulse_dict_from_pars(pulse_pars)
    min_delay = min(delays)
    readout_x1 = deepcopy(RO_pars)
    readout_x1['ref_point'] = 'end'
    readout_x2 = deepcopy(RO_pars)
    readout_x2['pulse_delay'] = RO_separation
    readout_x2['ref_point'] = 'start'
    probe_pulse = deepcopy(pulses['X180'])
    prep_pulses = [deepcopy(pulses[pulse_name]) for pulse_name in prep_pulses]
    for pulse in prep_pulses:
        pulse['pulse_delay'] = -2 * np.abs(min_delay)
    for i, tau in enumerate(delays):
        if i in cal_points[0] or i - len(delays) in cal_points[0]:
            seg = segment.Segment('segment_{}'.format(2 * i),
                                  [pulses['I'], RO_pars])
            seg_list.append(seg)
            seq.add(seg)
            seg = segment.Segment('segment_{}'.format(2 * i + 1),
                                  [pulses['I'], RO_pars])
            seg_list.append(seg)
            seq.add(seg)
        elif i in cal_points[1] or i - len(delays) in cal_points[1]:
            seg = segment.Segment('segment_{}'.format(2 * i),
                                  [pulses['X180'], RO_pars])
            seg_list.append(seg)
            seq.add(seg)
            seg = segment.Segment('segment_{}'.format(2 * i + 1),
                                  [pulses['X180'], RO_pars])
            seg_list.append(seg)
            seq.add(seg)
        else:
            probe_pulse['pulse_delay'] = tau - min_delay
            readout_x1['pulse_delay'] = -tau
            seg = segment.Segment(
                'segment_{}'.format(2 * i),
                prep_pulses + [probe_pulse, readout_x1, readout_x2])
            seg_list.append(seg)
            seq.add(seg)

    if upload:
        ps.Pulsar.get_instance().program_awgs(seq)
    if return_seq:
        return seq, seg_list
    else:
        return seq_name
def cphase_fringes(
    phases,
    q0_pulse_pars,
    q1_pulse_pars,
    RO_pars,
    swap_pars_q0,
    cphase_pars_q1,
    timings_dict,
    distortion_dict,
    verbose=False,
    upload=True,
    return_seq=False,
):
    """
    """
    preloaded_kernels_vec = preload_kernels_func(distortion_dict)
    original_delay = deepcopy(RO_pars)[0]["pulse_delay"]
    seq_name = "CPhase"
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    # print(q0_pulse_pars)
    q0_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q0_pulse_pars[0]), " q0")
    q1_pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(q1_pulse_pars[0]), " q1")

    pulse_dict = {}
    pulse_dict.update(q0_pulses)
    pulse_dict.update(q1_pulses)
    pulse_dict.update({"RO": RO_pars[0]})
    # print({'RO': RO_pars})

    # Timings
    buffer_mw_flux = timings_dict[0]["buffer_mw_flux"]
    buffer_flux_mw = timings_dict[0]["buffer_flux_mw"]
    msmt_buffer = timings_dict[0]["msmt_buffer"]
    dead_time = timings_dict[0]["dead_time"]
    # print(buffer_mw_flux,buffer_flux_mw,msmt_buffer,dead_time)

    # defining main pulses
    exc_pulse = deepcopy(pulse_dict["X180 q0"])
    exc_pulse["pulse_delay"] += 0.01e-6
    swap_pulse_1 = deepcopy(swap_pars_q0[0])
    # print(swap_pulse_1)
    swap_pulse_1["pulse_delay"] = buffer_mw_flux + exc_pulse["sigma"] * exc_pulse["nr_sigma"]

    ramsey_1 = deepcopy(pulse_dict["Y90 q1"])
    ramsey_1["pulse_delay"] = buffer_flux_mw + swap_pulse_1["length"]
    cphase_pulse = cphase_pars_q1[0]
    cphase_amp = cphase_pulse["amplitude"]
    cphase_pulse["pulse_delay"] = buffer_mw_flux + ramsey_1["sigma"] * ramsey_1["nr_sigma"]
    ramsey_2 = deepcopy(pulse_dict["X90 q1"])
    ramsey_2["pulse_delay"] = buffer_flux_mw + cphase_pulse["length"]

    swap_pulse_2 = deepcopy(swap_pars_q0[0])
    swap_pulse_2["pulse_delay"] = buffer_mw_flux + ramsey_2["sigma"] * ramsey_2["nr_sigma"]
    RO_pars[0]["pulse_delay"] = msmt_buffer + swap_pulse_2["length"]

    # defining compensation pulses
    swap_comp_1 = deepcopy(swap_pulse_1)
    swap_pulse_1["pulse_delay"] = RO_pars[0]["length"] + dead_time
    cphase_comp = deepcopy(cphase_pulse)
    swap_comp_2 = deepcopy(swap_pulse_2)

    dead_time_pulse = {
        "pulse_type": "SquarePulse",
        "pulse_delay": RO_pars[0]["pulse_delay"],
        "channel": swap_pars_q0[0]["channel"],
        "amplitude": 0,
        "length": dead_time,
    }

    for i, ph2 in enumerate(phases[0]):
        # print(ph2)
        ramsey_2["phase"] = ph2

        cphase_pulse["amplitude"] = cphase_amp
        pulse_list = [
            exc_pulse,
            swap_pulse_1,
            ramsey_1,
            cphase_pulse,
            ramsey_2,
            swap_pulse_2,
            RO_pars[0],
            swap_comp_1,
            cphase_comp,
            swap_comp_2,
            dead_time_pulse,
        ]
        el = multi_pulse_elt(2 * i, station, pulse_list)
        el_list.append(el)

        cphase_pulse["amplitude"] = 0.0
        pulse_list = [
            exc_pulse,
            swap_pulse_1,
            ramsey_1,
            cphase_pulse,
            ramsey_2,
            swap_pulse_2,
            RO_pars[0],
            swap_comp_1,
            cphase_comp,
            swap_comp_2,
            dead_time_pulse,
        ]
        el = multi_pulse_elt(2 * i + 1, station, pulse_list)
        el_list.append(el)

    # Compensations
    for i, el in enumerate(el_list):
        if distortion_dict is not None:
            el = distort_and_compensate(el, distortion_dict, preloaded_kernels_vec)
            el_list[i] = el
        seq.append_element(el, trigger_wait=True)
    cal_points = 4
    RO_pars[0]["pulse_delay"] = original_delay

    # Calibration points
    cal_points = [
        ["I q0", "I q1", "RO"],
        ["I q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["X180 q0", "I q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["I q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
        ["X180 q0", "X180 q1", "RO"],
    ]

    for i, pulse_comb in enumerate(cal_points):
        pulses = []
        for p in pulse_comb:
            pulses += [pulse_dict[p]]
        pulses[0]["pulse_delay"] += 0.01e-6

        el = multi_pulse_elt(2 * len(phases) + i, station, pulses)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    # upload
    if upload:
        station.components["AWG"].stop()
        station.pulsar.program_awg(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq
Exemplo n.º 17
0
def readout_photons_in_resonator_seq(delay_to_relax,
                                     delay_buffer,
                                     ramsey_times,
                                     RO_pars,
                                     pulse_pars,
                                     cal_points=((-4, -3), (-2, -1)),
                                     verbose=False,
                                     upload=True,
                                     return_seq=False,
                                     artificial_detuning=None):
    """
    The sequence consists of two readout pulses sandwitching two ramsey pulses
    inbetween. The delay between the first readout pulse and first ramsey pulse
    is swept, to measure the ac stark shift and dephasing from any residual
    photons.

    Important: This sequence includes two readouts per segment. For this reason
    the calibration points are also duplicated.

    Args:
        delay_ro_relax: delay between the end of the first readout
                        pulse and the start of the first ramsey pulse.

        pulse_pars: Pulse dictionary for the ramsey pulse.
        RO_pars: Pulse dictionary for the readout pulse.
        delay_buffer: delay between the start of the last ramsey pulse and the
                      start of the second readout pulse.
        ramsey_times: delays between ramsey pulses
        cal_points: True for default calibration points, False for no
                          calibration points or a list of two lists, containing
                          the indices of the calibration segments for the ground
                          and excited state.

    Returns:
        The sequence object and the element list if return_seq is True. Else
        return the sequence name.
    """
    raise NotImplementedError(
        'readout_photons_in_resonator_seq has not been '
        'converted to the latest waveform generation code and can not be used.'
    )

    if cal_points is True: cal_points = ((-4, -3), (-2, -1))
    elif cal_points is False or cal_points is None: cal_points = ((), ())

    seq_name = 'readout_photons_in_resonator_sequence'
    seq = sequence.Sequence(seq_name)
    el_list = []
    pulses = get_pulse_dict_from_pars(pulse_pars)
    ramsey_x1 = deepcopy(pulses['X90'])
    ramsey_x1['pulse_delay'] = delay_to_relax
    readout_x2 = deepcopy(RO_pars)
    readout_x2['pulse_delay'] = delay_buffer

    for i, tau in enumerate(ramsey_times):
        if i in cal_points[0] or i - len(ramsey_times) in cal_points[0]:
            el = multi_pulse_elt(2 * i, station, [pulses['I'], RO_pars])
            el_list.append(el)
            seq.append_element(el, trigger_wait=True)
            el = multi_pulse_elt(2 * i + 1, station, [pulses['I'], RO_pars])
            el_list.append(el)
            seq.append_element(el, trigger_wait=True)
        elif i in cal_points[1] or i - len(ramsey_times) in cal_points[1]:
            el = multi_pulse_elt(2 * i, station, [pulses['X180'], RO_pars])
            el_list.append(el)
            seq.append_element(el, trigger_wait=True)
            el = multi_pulse_elt(2 * i + 1, station, [pulses['X180'], RO_pars])
            el_list.append(el)
            seq.append_element(el, trigger_wait=True)
        else:
            ramsey_x2 = deepcopy(pulses['X90'])
            ramsey_x2['refpoint'] = 'start'
            ramsey_x2['pulse_delay'] = tau
            if artificial_detuning is not None:
                Dphase = (tau * artificial_detuning * 360) % 360
                ramsey_x2['phase'] += Dphase

            prep_pulse = [pulses['I'], pulses['X180']][i % 2]
            el = multi_pulse_elt(
                2 * i, station,
                [prep_pulse, RO_pars, ramsey_x1, ramsey_x2, readout_x2])
            el_list.append(el)
            seq.append_element(el, trigger_wait=True)

    if upload:
        station.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq_name
Exemplo n.º 18
0
def n_qubit_off_on(pulse_pars_list,
                   RO_pars_list,
                   return_seq=False,
                   parallel_pulses=False,
                   preselection=False,
                   upload=True,
                   RO_spacing=2000e-9):
    n = len(pulse_pars_list)
    seq_name = '{}_qubit_OffOn_sequence'.format(n)
    seq = sequence.Sequence(seq_name)
    seg_list = []

    RO_pars_list_presel = deepcopy(RO_pars_list)

    for i, RO_pars in enumerate(RO_pars_list):
        RO_pars['name'] = 'RO_{}'.format(i)
        RO_pars['element_name'] = 'RO'
        if i != 0:
            RO_pars['ref_point'] = 'start'
    for i, RO_pars_presel in enumerate(RO_pars_list_presel):
        RO_pars_presel['ref_pulse'] = RO_pars_list[-1]['name']
        RO_pars_presel['ref_point'] = 'start'
        RO_pars_presel['element_name'] = 'RO_presel'
        RO_pars_presel['pulse_delay'] = -RO_spacing

    # Create a dict with the parameters for all the pulses
    pulse_dict = dict()
    for i, pulse_pars in enumerate(pulse_pars_list):
        pars = pulse_pars.copy()
        if i == 0 and parallel_pulses:
            pars['ref_pulse'] = 'segment_start'
        if i != 0 and parallel_pulses:
            pars['ref_point'] = 'start'
        pulses = add_suffix_to_dict_keys(get_pulse_dict_from_pars(pars),
                                         ' {}'.format(i))
        pulse_dict.update(pulses)

    # Create a list of required pulses
    pulse_combinations = []

    for pulse_list in itertools.product(*(n * [['I', 'X180']])):
        pulse_comb = (n) * ['']
        for i, pulse in enumerate(pulse_list):
            pulse_comb[i] = pulse + ' {}'.format(i)
        pulse_combinations.append(pulse_comb)
    for i, pulse_comb in enumerate(pulse_combinations):
        pulses = []
        for j, p in enumerate(pulse_comb):
            pulses += [pulse_dict[p]]
        pulses += RO_pars_list
        if preselection:
            pulses = pulses + RO_pars_list_presel

        seg = segment.Segment('segment_{}'.format(i), pulses)
        seg_list.append(seg)
        seq.add(seg)

    repeat_dict = {}
    repeat_pattern = ((1.0 + int(preselection)) * len(pulse_combinations), 1)
    for i, RO_pars in enumerate(RO_pars_list):
        repeat_dict = seq.repeat(RO_pars, None, repeat_pattern)

    if upload:
        ps.Pulsar.get_instance().program_awgs(seq)
    if return_seq:
        return seq, seg_list
    else:
        return seq_name