def interleaved_pulse_list_list_equatorial_seq(
        qubit_names,
        operation_dict,
        interleaved_pulse_list_list,
        phases,
        pihalf_spacing=None,
        prep_params=None,
        cal_points=None,
        sequence_name='equatorial_sequence',
        upload=True):
    prep_params = {} if prep_params is None else prep_params
    seq = sequence.Sequence(sequence_name)
    for i, interleaved_pulse_list in enumerate(interleaved_pulse_list_list):
        for j, phase in enumerate(phases):
            seg = interleaved_pulse_list_equatorial_seg(
                qubit_names,
                operation_dict,
                interleaved_pulse_list,
                phase,
                pihalf_spacing=pihalf_spacing,
                prep_params=prep_params,
                segment_name=f'segment_{i}_{j}')
            seq.add(seg)
    if cal_points is not None:
        seq.extend(cal_points.create_segments(operation_dict, **prep_params))
    if upload:
        ps.Pulsar.get_instance().program_awgs(seq)
    return seq, np.arange(seq.n_acq_elements())
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.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    if return_seq:
        return seq, el_list
    else:
        return seq_name
def n_qubit_ref_seq(qubit_names,
                    operation_dict,
                    ref_desc,
                    upload=True,
                    return_seq=False,
                    preselection=False,
                    ro_spacing=1e-6):
    """
        Calibration points for arbitrary combinations

        Arguments:
            qubits: List of calibrated qubits for obtaining the pulse
                dictionaries.
            ref_desc: Description of the calibration sequence. Dictionary
                name of the state as key, and list of pulses names as values.
    """

    # create the elements
    seq_name = 'Calibration'
    seq = sequence.Sequence(seq_name)
    seg_list = []

    # calibration elements
    # calibration_sequences = []
    # for pulses in ref_desc:
    #     calibration_sequences.append(
    #         [pulse+' '+qb for qb, pulse in zip(qubit_names, pulses)])

    calibration_sequences = []
    for pulses in ref_desc:
        calibration_sequence_new = []
        for i, pulse in enumerate(pulses):
            if i == 0:
                qb = ' ' + qubit_names[i]
            else:
                qb = 's ' + qubit_names[i]
            calibration_sequence_new.append(pulse + qb)
        calibration_sequences.append(calibration_sequence_new)

    for i, calibration_sequence in enumerate(calibration_sequences):
        pulse_list = []
        pulse_list.extend(
            [operation_dict[pulse] for pulse in calibration_sequence])
        ro_pulses = generate_mux_ro_pulse_list(qubit_names, operation_dict)
        pulse_list.extend(ro_pulses)

        if preselection:
            ro_pulses_presel = generate_mux_ro_pulse_list(
                qubit_names, operation_dict, 'RO_presel', 'start', -ro_spacing)
            pulse_list.extend(ro_pulses_presel)
        seg = segment.Segment('calibration_{}'.format(i), pulse_list)
        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
예제 #4
0
def ramsey_seq_multiple_detunings(times,
                                  pulse_pars,
                                  RO_pars,
                                  artificial_detunings=None,
                                  cal_points=True,
                                  upload=True,
                                  return_seq=False):
    '''
    Ramsey sequence for a single qubit using the tektronix.
    SSB_Drag pulse is used for driving, simple modualtion used for RO
    !!! Each value in the times array must be repeated len(artificial_detunings)
    times!!!
    Input pars:
        times:               array of times between (start of) pulses (s)
        pulse_pars:          dict containing the pulse parameters
        RO_pars:             dict containing the RO parameters
        artificial_detunings: list of artificial_detunings (Hz) implemented
                              using phase
        cal_points:          whether to use calibration points or not
    '''
    seq_name = 'Ramsey_sequence_multiple_detunings'
    seq = sequence.Sequence(seq_name)
    ps.Pulsar.get_instance().update_channel_settings()
    seg_list = []
    # First extract values from input, later overwrite when generating
    # waveforms
    pulses = get_pulse_dict_from_pars(pulse_pars)

    pulse_pars_x2 = deepcopy(pulses['X90'])
    pulse_pars_x2['ref_point'] = 'start'
    for i, tau in enumerate(times):
        pulse_pars_x2['pulse_delay'] = tau
        art_det = artificial_detunings[i % len(artificial_detunings)]

        if art_det is not None:
            Dphase = ((tau - times[0]) * art_det * 360) % 360
            pulse_pars_x2['phase'] = Dphase

        if cal_points and (i == (len(times) - 4) or i == (len(times) - 3)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['I'], RO_pars])
        elif cal_points and (i == (len(times) - 2) or i == (len(times) - 1)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['X180'], RO_pars])
        else:
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['X90'], pulse_pars_x2, RO_pars])
        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
예제 #5
0
def ramsey_seq_VZ(times,
                  pulse_pars,
                  RO_pars,
                  artificial_detuning=None,
                  cal_points=True,
                  upload=True,
                  return_seq=False):
    '''
    Ramsey sequence for a single qubit using the tektronix.
    SSB_Drag pulse is used for driving, simple modualtion used for RO
    Input pars:
        times:               array of times between (start of) pulses (s)
        pulse_pars:          dict containing the pulse parameters
        RO_pars:             dict containing the RO parameters
        artificial_detuning: artificial_detuning (Hz) implemented using phase
        cal_points:          whether to use calibration points or not
    '''
    if np.any(times > 1e-3):
        logging.warning('The values in the times array might be too large.'
                        'The units should be seconds.')

    seq_name = 'Ramsey_sequence'
    seq = sequence.Sequence(seq_name)
    seg_list = []
    # First extract values from input, later overwrite when generating
    # waveforms
    pulses = get_pulse_dict_from_pars(pulse_pars)

    pulse_pars_x2 = deepcopy(pulses['X90'])
    pulse_pars_x2['ref_point'] = 'start'
    for i, tau in enumerate(times):
        pulse_pars_x2['pulse_delay'] = tau

        if artificial_detuning is not None:
            Dphase = ((tau - times[0]) * artificial_detuning * 360) % 360
        else:
            Dphase = ((tau - times[0]) * 1e6 * 360) % 360
        Z_gate = Z(Dphase, pulse_pars)

        if cal_points and (i == (len(times) - 4) or i == (len(times) - 3)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['I'], RO_pars])
        elif cal_points and (i == (len(times) - 2) or i == (len(times) - 1)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['X180'], RO_pars])
        else:
            pulse_list = [pulses['X90'], Z_gate, pulse_pars_x2, RO_pars]
            seg = segment.Segment('segment_{}'.format(i), pulse_list)
        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
예제 #6
0
def pulse_list_list_seq(pulse_list_list,
                        name='pulse_list_list_sequence',
                        upload=True,
                        fast_mode=False):
    seq = sequence.Sequence(name)
    for i, pulse_list in enumerate(pulse_list_list):
        seq.add(
            segment.Segment('segment_{}'.format(i),
                            pulse_list,
                            fast_mode=fast_mode))
    if upload:
        ps.Pulsar.get_instance().program_awgs(seq)
    return seq
def n_qubit_tomo_seq(qubit_names,
                     operation_dict,
                     prep_sequence=None,
                     prep_name=None,
                     rots_basis=tomo.DEFAULT_BASIS_ROTS,
                     upload=True,
                     return_seq=False,
                     preselection=False,
                     ro_spacing=1e-6):
    """

    """

    # create the sequence
    if prep_name is None:
        seq_name = 'N-qubit tomography'
    else:
        seq_name = prep_name + ' tomography'
    seq = sequence.Sequence(seq_name)
    seg_list = []

    if prep_sequence is None:
        prep_sequence = ['Y90 ' + qubit_names[0]]

    # tomography elements
    tomography_sequences = get_tomography_pulses(*qubit_names,
                                                 basis_pulses=rots_basis)
    for i, tomography_sequence in enumerate(tomography_sequences):
        pulse_list = [operation_dict[pulse] for pulse in prep_sequence]
        # tomography_sequence.append('RO mux')
        # if preselection:
        #     tomography_sequence.append('RO mux_presel')
        #     tomography_sequence.append('RO presel_dummy')
        pulse_list.extend(
            [operation_dict[pulse] for pulse in tomography_sequence])
        ro_pulses = generate_mux_ro_pulse_list(qubit_names, operation_dict)
        pulse_list.extend(ro_pulses)

        if preselection:
            ro_pulses_presel = generate_mux_ro_pulse_list(
                qubit_names, operation_dict, 'RO_presel', 'start', -ro_spacing)
            pulse_list.extend(ro_pulses_presel)
        seg = segment.Segment('tomography_{}'.format(i), pulse_list)
        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
예제 #8
0
def echo_seq(times,
             pulse_pars,
             RO_pars,
             artificial_detuning=None,
             cal_points=True,
             upload=True,
             return_seq=False):
    '''
    Echo sequence for a single qubit using the tektronix.
    Input pars:
        times:          array of times between (start of) pulses (s)
        artificial_detuning: artificial_detuning (Hz) implemented using phase
        pulse_pars:     dict containing the pulse parameters
        RO_pars:        dict containing the RO parameters
        cal_points:     whether to use calibration points or not
    '''
    seq_name = 'Echo_sequence'
    seq = sequence.Sequence(seq_name)
    seg_list = []

    pulses = get_pulse_dict_from_pars(pulse_pars)
    center_X180 = deepcopy(pulses['X180'])
    final_X90 = deepcopy(pulses['X90'])
    center_X180['ref_point'] = 'start'
    final_X90['ref_point'] = 'start'

    for i, tau in enumerate(times):
        center_X180['pulse_delay'] = tau / 2
        final_X90['pulse_delay'] = tau / 2
        if artificial_detuning is not None:
            final_X90['phase'] = (tau - times[0]) * artificial_detuning * 360
        if cal_points and (i == (len(times) - 4) or i == (len(times) - 3)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['I'], RO_pars])
        elif cal_points and (i == (len(times) - 2) or i == (len(times) - 1)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['X180'], RO_pars])
        else:
            seg = segment.Segment(
                'segment_{}'.format(i),
                [pulses['X90'], center_X180, final_X90, RO_pars])
        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 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
예제 #10
0
def single_state_active_reset(operation_dict,
                              qb_name,
                              state='e',
                              upload=True,
                              prep_params={}):
    '''
    OffOn sequence for a single qubit using the tektronix.
    SSB_Drag pulse is used for driving, simple modualtion used for RO
    Input pars:
        pulse_pars:          dict containing the pulse parameters
        RO_pars:             dict containing the RO parameters
        pulse_pars_2nd:      dict containing the pulse parameters of ef transition.
                             Required if state is 'f'.
        Initialize:          adds an exta measurement before state preparation
                             to allow initialization by post-selection
        Post-measurement delay:  should be sufficiently long to avoid
                             photon-induced gate errors when post-selecting.
        state:               specifies for which state a pulse should be
                             generated (g,e,f)
        preselection:        adds an extra readout pulse before other pulses.
    '''
    seq_name = 'single_state_sequence'
    seq = sequence.Sequence(seq_name)

    # Create dicts with the parameters for all the pulses
    state_ops = dict(g=["I", "RO"],
                     e=["X180", "RO"],
                     f=["X180", "X180_ef", "RO"])
    pulses = [
        deepcopy(operation_dict[op])
        for op in add_suffix(state_ops[state], " " + qb_name)
    ]

    #add preparation pulses
    pulses_with_prep = \
        add_preparation_pulses(pulses, operation_dict, [qb_name], **prep_params)

    seg = segment.Segment('segment_{}_level'.format(state), pulses_with_prep)
    seq.add(seg)

    # reuse sequencer memory by repeating readout pattern
    seq.repeat_ro(f"RO {qb_name}", operation_dict)

    if upload:
        ps.Pulsar.get_instance().program_awgs(seq)

    return seq, np.arange(seq.n_acq_elements())
def avoided_crossing_spec_seq(operation_dict, q0, q1, RO_target,
                              verbose=False,
                              upload=True):

    seq_name = 'avoidec_crossing_spec'
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    sequencer_config = operation_dict['sequencer_config']

    # N.B. Identities not needed in all cases
    pulse_combinations = ['X180 '+q0, 'SpecPulse '+q1, 'RO '+RO_target]
    pulses = []
    for p in pulse_combinations:
        pulses += [operation_dict[p]]
    el = multi_pulse_elt(0, station, pulses, sequencer_config)
    el_list.append(el)
    seq.append_element(el, trigger_wait=True)
    if upload:
        station.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    return seq, el_list
예제 #12
0
def over_under_rotation_seq(qb_name,
                            nr_pi_pulses_array,
                            operation_dict,
                            pi_pulse_amp=None,
                            cal_points=True,
                            upload=True):
    seq_name = 'Over-under rotation sequence'
    seq = sequence.Sequence(seq_name)
    seg_list = []
    X90 = deepcopy(operation_dict['X90 ' + qb_name])
    X180 = deepcopy(operation_dict['X180 ' + qb_name])
    if pi_pulse_amp is not None:
        X90['amplitude'] = pi_pulse_amp / 2
        X180['amplitude'] = pi_pulse_amp

    for i, N in enumerate(nr_pi_pulses_array):
        if cal_points and (i == (len(nr_pi_pulses_array) - 4)
                           or i == (len(nr_pi_pulses_array) - 3)):
            seg = segment.Segment('segment_{}'.format(i), [
                operation_dict['I ' + qb_name], operation_dict['RO ' + qb_name]
            ])
        elif cal_points and (i == (len(nr_pi_pulses_array) - 2)
                             or i == (len(nr_pi_pulses_array) - 1)):
            seg = segment.Segment('segment_{}'.format(i), [
                operation_dict['X180 ' + qb_name],
                operation_dict['RO ' + qb_name]
            ])
        else:
            pulse_list = [X90]
            pulse_list += N * [X180]
            pulse_list += [operation_dict['RO ' + qb_name]]
            seg = segment.Segment('segment_{}'.format(i), pulse_list)

        seg_list.append(seg)
        seq.add(seg)
    if upload:
        ps.Pulsar.get_instance().program_awgs(seq)
    return
def two_qubit_tomo_cphase_cardinal(cardinal_state,
                        operation_dict,
                        qS,
                        qCZ,
                        RO_target,
                        distortion_dict,
                        CZ_disabled=False,
                        cal_points_with_flux_pulses=True,
                        verbose=False,
                        upload=True):
    '''
        qS is swap qubit
        qCZ is cphase qubit
    '''
    sequencer_config = operation_dict['sequencer_config']

    seq_name = '2_qubit_CPhase_Cardinal_Tomo_%d_seq' % cardinal_state
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    tomo_list_qS = []
    tomo_list_qCZ = []
    # Tomo pulses span a basis covering all the cardinal points
    tomo_pulses = ['I ', 'X180 ', 'Y90 ', 'mY90 ', 'X90 ', 'mX90 ']
    for tp in tomo_pulses:
        tomo_list_qS += [tp+qS]
        tomo_list_qCZ += [tp+qCZ]

    ###########################
    # Defining sub sequences #
    ###########################
    # This forms the base sequence, note that gate1, gate2 and after_pulse will
    # be replaced to prepare the desired state and tomo1 and tomo2 will be
    # replaced with tomography pulses
    base_sequence = (
        ['gate1 ' + qS, 'gate2 ' + qCZ,
         'SWAP '+qS, 'CZ ' + qCZ, 'rSWAP ' + qS,
         'SWAP_corr ' + qS, 'CZ_corr ' + qCZ,
         'after_pulse ' + qCZ, 'tomo1 '+qCZ, 'tomo2 '+qS, 'RO '+RO_target])

    # Calibration points
    # every calibration point is repeated 7 times to have 64 elts in total
    cal_points = [['I '+qCZ, 'I '+qS, 'RO '+RO_target]]*7 +\
                  [['I '+qCZ, 'X180 '+qS, 'RO '+RO_target]]*7 +\
                  [['X180 '+qCZ, 'I '+qS, 'RO '+RO_target]]*7 +\
                  [['X180 '+qCZ, 'X180 '+qS, 'RO '+RO_target]]*7

    if CZ_disabled:
        operation_dict['CZ '+qCZ]['amplitude'] = 0
        operation_dict['CZ '+qCZ]['phase_corr_pulse_amp'] = 0

    ################################################
    # Creating additional pulses for this sequence #
    ################################################
    # the recovery SWAP is identical to the regular SWAP operation, unless
    # an rSWAP is explicitly contained in the operation dict
    if ('rSWAP ' + qS) not in operation_dict.keys():
        operation_dict['rSWAP ' + qS] = deepcopy(operation_dict['SWAP ' + qS])
    operation_dict['CZ_corr ' + qCZ]['refpoint'] = 'simultaneous'

    ################
    # cardinal states  #
    ################
    # here select the qubit gates (depending on cardinal_state)
    prep_idx_qS = int(cardinal_state % 6)
    prep_idx_qCZ = int(((cardinal_state - prep_idx_qS)/6) % 6)

    print('Compensation qCP {:.3f}'.format(
        operation_dict['CZ_corr ' + qCZ]['amplitude']))
    print('Compensation qS {:.3f}'.format(
        operation_dict['SWAP_corr ' + qS]['amplitude']))

    ########################################################
    #  Here the actual pulses of all elements get defined  #
    ########################################################
    # We start by replacing the state prepartion pulses
    base_sequence[0] = tomo_list_qS[prep_idx_qS]
    base_sequence[1] = tomo_list_qCZ[prep_idx_qCZ]
    base_sequence[7] = 'I ' + qCZ

    seq_pulse_list = []

    for i in range(36):
        tomo_idx_qS = int(i % 6)
        tomo_idx_qCZ = int(((i - tomo_idx_qS)/6) % 6)
        base_sequence[8] = tomo_list_qCZ[tomo_idx_qCZ]
        base_sequence[9] = tomo_list_qS[tomo_idx_qS]
        seq_pulse_list += [deepcopy(base_sequence)]
    print(len(cal_points))
    for cal_pulses in cal_points:
        if cal_points_with_flux_pulses:
            base_sequence[0] = 'I ' + qS
            base_sequence[1] = 'I ' + qCZ
            base_sequence[7] = 'I ' + qCZ
            base_sequence[-3:] = cal_pulses
            seq_pulse_list += [deepcopy(base_sequence)]
        else:
            seq_pulse_list += [cal_pulses]

    for i, pulse_list in enumerate(seq_pulse_list):
        pulses = []
        for p in pulse_list:
            pulses += [operation_dict[p]]
        el = multi_pulse_elt(i, station, pulses, sequencer_config)
        if distortion_dict is not None:
            print('\rDistorting element {}/{} '.format(i+1,
                                                       len(seq_pulse_list)),
                  end='')
            el = distort_and_compensate(
                el, distortion_dict)
        el_list.append(el)
        seq.append_element(el, trigger_wait=True)

    station.pulsar.program_awgs(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_AllXY(operation_dict, q0='q0', q1='q1', RO_target='all',
                    sequence_type='simultaneous',
                    replace_q1_pulses_X180=False,
                    double_points=True,
                    verbose=False, upload=True,
                    return_seq=False):
    """
    Performs an AllXY sequence on two qubits.
    Has the option of replacing pulses on q1 with pi pulses

    Args:
        operation_dict (dict) : dictionary containing all pulse parameters
        q0, q1         (str) : target qubits for the sequence
        RO_target      (str) : target for the RO, can be a qubit name or 'all'
        sequence_type  (str) : sequential | interleaved | simultaneous | sandwiched
                              q0|q0|q1|q1   q0|q1|q0|q1   q01|q01      q1|q0|q0|q1
            describes the order of the AllXY pulses
        replace_q1_pulses_X180 (bool) : if True replaces all pulses on q1 with
            X180 pulses.

        double_points (bool) : if True measures each point in the AllXY twice
        verbose       (bool) : verbose sequence generation
        upload        (bool) :
    """
    seq_name = 'two_qubit_AllXY_{}_{}'.format(q0, q1)
    seq = sequence.Sequence(seq_name)
    station.pulsar.update_channel_settings()
    el_list = []
    sequencer_config = operation_dict['sequencer_config']

    AllXY_pulse_combinations = [['I ', 'I '], ['X180 ', 'X180 '], ['Y180 ', 'Y180 '],
                                ['X180 ', 'Y180 '], ['Y180 ', 'X180 '],
                                ['X90 ', 'I '], ['Y90 ', 'I '], [
                                    'X90 ', 'Y90 '],
                                ['Y90 ', 'X90 '], ['X90 ', 'Y180 '], [
                                    'Y90 ', 'X180 '],
                                ['X180 ', 'Y90 '], ['Y180 ', 'X90 '], [
                                    'X90 ', 'X180 '],
                                ['X180 ', 'X90 '], ['Y90 ', 'Y180 '], [
                                    'Y180 ', 'Y90 '],
                                ['X180 ', 'I '], ['Y180 ', 'I '], [
                                    'X90 ', 'X90 '],
                                ['Y90 ', 'Y90 ']]
    if double_points:
        AllXY_pulse_combinations = [val for val in AllXY_pulse_combinations
                                    for _ in (0, 1)]

    if sequence_type == 'simultaneous':
        operation_dict = deepcopy(operation_dict)  # prevents overwriting of dict
        for key in operation_dict.keys():
            if q1 in key:
                operation_dict[key]['refpoint'] = 'start'
                operation_dict[key]['pulse_delay'] = 0

    pulse_list = []
    if not replace_q1_pulses_X180:
        for pulse_comb in AllXY_pulse_combinations:
            if sequence_type == 'interleaved' or sequence_type == 'simultaneous':
                pulse_list += [[pulse_comb[0] + q0] + [pulse_comb[0] + q1] +
                               [pulse_comb[1] + q0] + [pulse_comb[1] + q1] +
                               ['RO ' + RO_target]]
            elif sequence_type == 'sequential':
                pulse_list += [[pulse_comb[0] + q0] + [pulse_comb[1] + q0] +
                               [pulse_comb[0] + q1] + [pulse_comb[1] + q1] +
                               ['RO ' + RO_target]]
            elif sequence_type == 'sandwiched':
                pulse_list += [[pulse_comb[0] + q1] + [pulse_comb[0] + q0] +
                               [pulse_comb[1] + q0] + [pulse_comb[1] + q1] +
                               ['RO ' + RO_target]]
            else:
                raise ValueError("sequence_type {} must be in".format(sequence_type) +
                                 " ['interleaved', simultaneous', 'sequential', 'sandwiched']")
    else:
        for pulse_comb in AllXY_pulse_combinations:
            if sequence_type == 'interleaved' or sequence_type == 'simultaneous':
                pulse_list += [[pulse_comb[0] + q0] + ['X180 ' + q1] +
                               [pulse_comb[1] + q0] + ['X180 ' + q1] +
                               ['RO ' + RO_target]]
            elif sequence_type == 'sequential':
                pulse_list += [[pulse_comb[0] + q0] + [pulse_comb[1] + q0] +
                               ['X180 ' + q1] + ['X180 ' + q1] +
                               ['RO ' + RO_target]]
            elif sequence_type == 'sandwiched':
                pulse_list += [['X180 ' + q1] + [pulse_comb[0] + q0] +
                               [pulse_comb[1] + q0] + ['X180 ' + q1] +
                               ['RO ' + RO_target]]
            else:
                raise ValueError("sequence_type {} must be in".format(sequence_type) +
                                 " ['interleaved', simultaneous', 'sequential', 'sandwiched']")

    for i, pulse_comb in enumerate(pulse_list):
        pulses = []
        for p in pulse_comb:
            pulses += [operation_dict[p]]

        el = multi_pulse_elt(i, station, pulses, sequencer_config)
        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
예제 #17
0
def ramsey_seq_Echo(times,
                    pulse_pars,
                    RO_pars,
                    nr_echo_pulses=4,
                    artificial_detuning=None,
                    cal_points=True,
                    cpmg_scheme=True,
                    upload=True,
                    return_seq=False):
    '''
    Ramsey sequence for a single qubit using the tektronix.
    SSB_Drag pulse is used for driving, simple modualtion used for RO
    Input pars:
        times:               array of times between (start of) pulses (s)
        pulse_pars:          dict containing the pulse parameters
        RO_pars:             dict containing the RO parameters
        artificial_detuning: artificial_detuning (Hz) implemented using phase
        cal_points:          whether to use calibration points or not
    '''
    if np.any(times > 1e-3):
        logging.warning('The values in the times array might be too large.'
                        'The units should be seconds.')

    seq_name = 'Ramsey_sequence'
    seq = sequence.Sequence(seq_name)
    seg_list = []
    # First extract values from input, later overwrite when generating
    # waveforms
    pulses = get_pulse_dict_from_pars(pulse_pars)

    pulse_pars_x2 = deepcopy(pulses['X90'])
    pulse_pars_x2['ref_point'] = 'start'

    X180_pulse = deepcopy(pulses['X180'])
    Echo_pulses = nr_echo_pulses * [X180_pulse]
    DRAG_length = pulse_pars['nr_sigma'] * pulse_pars['sigma']

    for i, tau in enumerate(times):
        if artificial_detuning is not None:
            Dphase = ((tau - times[0]) * artificial_detuning * 360) % 360
            pulse_pars_x2['phase'] = Dphase

        if cal_points and (i == (len(times) - 4) or i == (len(times) - 3)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['I'], RO_pars])
        elif cal_points and (i == (len(times) - 2) or i == (len(times) - 1)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['X180'], RO_pars])
        else:
            X90_separation = tau - DRAG_length
            if cpmg_scheme:
                if i == 0:
                    print('cpmg')
                echo_pulse_delay = (X90_separation -
                                    nr_echo_pulses*DRAG_length) / \
                                    nr_echo_pulses
                if echo_pulse_delay < 0:
                    pulse_pars_x2['pulse_delay'] = tau
                    pulse_dict_list = [pulses['X90'], pulse_pars_x2, RO_pars]
                else:
                    pulse_dict_list = [pulses['X90']]
                    start_end_delay = echo_pulse_delay / 2
                    for p_nr, pulse_dict in enumerate(Echo_pulses):
                        pd = deepcopy(pulse_dict)
                        pd['ref_point'] = 'end'
                        pd['pulse_delay'] = \
                            (start_end_delay if p_nr == 0 else echo_pulse_delay)
                        pulse_dict_list.append(pd)

                    pulse_pars_x2['ref_point'] = 'end'
                    pulse_pars_x2['pulse_delay'] = start_end_delay
                    pulse_dict_list += [pulse_pars_x2, RO_pars]
            else:
                if i == 0:
                    print('UDD')
                pulse_positions_func = \
                    lambda idx, N: np.sin(np.pi*idx/(2*N+2))**2
                pulse_delays_func = (lambda idx, N: X90_separation *
                                     (pulse_positions_func(idx, N) -
                                      pulse_positions_func(idx - 1, N)) - (
                                          (0.5
                                           if idx == 1 else 1) * DRAG_length))

                if nr_echo_pulses * DRAG_length > X90_separation:
                    pulse_pars_x2['pulse_delay'] = tau
                    pulse_dict_list = [pulses['X90'], pulse_pars_x2, RO_pars]
                else:
                    pulse_dict_list = [pulses['X90']]
                    for p_nr, pulse_dict in enumerate(Echo_pulses):
                        pd = deepcopy(pulse_dict)
                        pd['ref_point'] = 'end'
                        pd['pulse_delay'] = pulse_delays_func(
                            p_nr + 1, nr_echo_pulses)
                        pulse_dict_list.append(pd)

                    pulse_pars_x2['ref_point'] = 'end'
                    pulse_pars_x2['pulse_delay'] = pulse_delays_func(
                        1, nr_echo_pulses)
                    pulse_dict_list += [pulse_pars_x2, RO_pars]

            seg = segment.Segment('segment_{}'.format(i), pulse_dict_list)

        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
예제 #18
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
예제 #19
0
def Ramsey_with_flux_pulse_meas_seq(thetas, qb, X90_separation, verbose=False,
                                    upload=True, return_seq=False,
                                    cal_points=False):
    '''
    Performs a Ramsey with interleaved Flux pulse

    Timings of sequence
           <----- |fluxpulse|
        |X90|  -------------------     |X90|  ---  |RO|
                                     sweep phase

    timing of the flux pulse relative to the center of the first X90 pulse

    Args:
        thetas: numpy array of phase shifts for the second pi/2 pulse
        qb: qubit object (must have the methods get_operation_dict(),
        get_drive_pars() etc.
        X90_separation: float (separation of the two pi/2 pulses for Ramsey
        verbose: bool
        upload: bool
        return_seq: bool

    Returns:
        if return_seq:
          seq: qcodes sequence
          el_list: list of pulse elements
        else:
            seq_name: string
    '''
    raise NotImplementedError(
        'Ramsey_with_flux_pulse_meas_seq has not been '
        'converted to the latest waveform generation code and can not be used.')

    qb_name = qb.name
    operation_dict = qb.get_operation_dict()
    pulse_pars = qb.get_drive_pars()
    RO_pars = qb.get_RO_pars()
    seq_name = 'Measurement_Ramsey_sequence_with_Flux_pulse'
    seq = sequence.Sequence(seq_name)
    el_list = []

    pulses = get_pulse_dict_from_pars(pulse_pars)
    flux_pulse = operation_dict["flux "+qb_name]
    # Used for checking dynamic phase compensation
    # if flux_pulse['amplitude'] != 0:
    #     flux_pulse['basis_rotation'] = {qb_name: -80.41028958782647}

    flux_pulse['ref_point'] = 'end'
    X90_2 = deepcopy(pulses['X90'])
    X90_2['pulse_delay'] = X90_separation - flux_pulse['pulse_delay'] \
                            - X90_2['nr_sigma']*X90_2['sigma']
    X90_2['ref_point'] = 'start'

    for i, theta in enumerate(thetas):
        X90_2['phase'] = theta*180/np.pi
        if cal_points and (i == (len(thetas)-4) or i == (len(thetas)-3)):
            el = multi_pulse_elt(i, station, [RO_pars])
        elif cal_points and (i == (len(thetas)-2) or i == (len(thetas)-1)):
            flux_pulse['amplitude'] = 0
            el = multi_pulse_elt(i, station,
                                 [pulses['X90'], flux_pulse, X90_2, RO_pars])
        else:
            el = multi_pulse_elt(i, station,
                                 [pulses['X90'], flux_pulse, X90_2, RO_pars])
        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
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
예제 #21
0
def cos_seq(
    amplitude,
    frequency,
    channels,
    phases,
    marker_channels=None,
    marker_lenght=20e-9,
    verbose=False,
    alphas=[1],
    phi_skews=[0],
):
    '''
    Cosine  sequence, plays a continuous cos on the specified channel


    Input pars:
        amplitude (float): amplitude in Vpp
        frequency (float): frequency in Hz
        channels (list[(str)]: channels on which to set a cos
        phases (list[(float)]: phases in degree

        marker_channels (list[(str)]: optionally specify markers to play

    '''
    raise NotImplementedError(
        'cos_seq has not been '
        'converted to the latest waveform generation code and can not be used.'
    )

    seq_name = 'ModSquare'
    seq = sequence.Sequence(seq_name)
    el_list = []

    base_pars = {
        'pulse_type': 'ModSquare',
        'mod_frequency': frequency,
        'length': 2e-6,
        'amplitude': amplitude,
        'pulse_delay': 0
    }
    marker_pars = {
        'pulse_type': 'SquarePulse',
        'length': marker_lenght,
        'amplitude': 1,
        'pulse_delay': 10e-9
    }

    pulse_list = []
    for i, phase in enumerate(phases):
        pulse = deepcopy(base_pars)
        pulse['I_channel'] = channels[i * 2]
        pulse['Q_channel'] = channels[i * 2 + 1]
        pulse['phase'] = phase
        pulse['alpha'] = alphas[i]
        pulse['phi_skew'] = phi_skews[i]
        pulse_list.append(pulse)
        # copy first element and set extra wait
    if marker_channels != None:
        for i, marker_channel in enumerate(marker_channels):
            pulse = deepcopy(marker_pars)
            pulse['channel'] = marker_channel
            if i != 0:
                pulse['pulse_delay'] = 0
            pulse_list.append(pulse)

    el = multi_pulse_elt(0, station, pulse_list)
    el_list.append(el)
    seq.append_element(el, trigger_wait=False)
    # seq.append_element(el, trigger_wait=False)
    station.pulsar.program_awgs(seq, *el_list, verbose=verbose)
    return seq_name
예제 #22
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 Ramsey_add_pulse_seq(times,
                         measured_qubit_name,
                         pulsed_qubit_name,
                         operation_dict,
                         artificial_detuning=None,
                         cal_points=True,
                         verbose=False,
                         upload=True,
                         return_seq=False):
    raise NotImplementedError(
        'Ramsey_add_pulse_seq has not been '
        'converted to the latest waveform generation code and can not be used.'
    )

    if np.any(times > 1e-3):
        logging.warning('The values in the times array might be too large.'
                        'The units should be seconds.')

    seq_name = 'Ramsey_with_additional_pulse_sequence'
    seq = sequence.Sequence(seq_name)
    el_list = []

    pulse_pars_x1 = deepcopy(operation_dict['X90 ' + measured_qubit_name])
    pulse_pars_x1['refpoint'] = 'end'
    pulse_pars_x2 = deepcopy(pulse_pars_x1)
    pulse_pars_x2['refpoint'] = 'start'
    RO_pars = operation_dict['RO ' + measured_qubit_name]
    add_pulse_pars = deepcopy(operation_dict['X180 ' + pulsed_qubit_name])

    for i, tau in enumerate(times):
        if cal_points and (i == (len(times) - 4) or i == (len(times) - 3)):
            el = multi_pulse_elt(
                i, station,
                [operation_dict['I ' + measured_qubit_name], RO_pars])
        elif cal_points and (i == (len(times) - 2) or i == (len(times) - 1)):
            el = multi_pulse_elt(
                i, station,
                [operation_dict['X180 ' + measured_qubit_name], RO_pars])
        else:
            pulse_pars_x2['pulse_delay'] = tau
            if artificial_detuning is not None:
                Dphase = ((tau - times[0]) * artificial_detuning * 360) % 360
                pulse_pars_x2['phase'] = Dphase

            if i % 2 == 0:
                el = multi_pulse_elt(i, station, [
                    operation_dict['X90 ' + measured_qubit_name],
                    pulse_pars_x2, RO_pars
                ])
            else:
                el = multi_pulse_elt(
                    i,
                    station,
                    [
                        add_pulse_pars,
                        pulse_pars_x1,
                        # [pulse_pars_x1, add_pulse_pars,
                        pulse_pars_x2,
                        RO_pars
                    ])
        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
예제 #24
0
def mixer_calibration_sequence(trigger_separation,
                               amplitude,
                               trigger_channel=None,
                               RO_pars=None,
                               pulse_I_channel='AWG_ch1',
                               pulse_Q_channel='AWG_ch2',
                               f_pulse_mod=0,
                               phi_skew=0,
                               alpha=1,
                               upload=True):
    raise NotImplementedError(
        'mixer_calibration_sequence has not been '
        'converted to the latest waveform generation code and can not be used.'
    )

    if trigger_channel is not None:
        RO_trigger = {
            'pulse_type': 'SquarePulse',
            'channel': trigger_channel,
            'length': 20e-9,
            'amplitude': 1.,
            'pulse_delay': 0
        }
    elif RO_pars is not None:
        RO_trigger = RO_pars
        trigger_channel = RO_pars['acq_marker_channel']
    else:
        raise ValueError('Set either RO_pars or trigger_channel')

    pulses = [RO_trigger]
    channels = [trigger_channel]
    channels += station.sequencer_config['slave_AWG_trig_channels']
    if pulse_I_channel is not None:
        cos_pulse = {
            'pulse_type': 'CosPulse',
            'channel': pulse_I_channel,
            'frequency': f_pulse_mod,
            'length':
            trigger_separation - station.pulsar.inter_element_spacing(),
            'phase': phi_skew,
            'amplitude': amplitude * alpha,
            'pulse_delay': 0,
            'refpoint': 'simultaneous'
        }
        pulses.append(cos_pulse)
        channels.append(pulse_I_channel)
    if pulse_Q_channel is not None:
        sin_pulse = {
            'pulse_type': 'CosPulse',
            'channel': pulse_Q_channel,
            'frequency': f_pulse_mod,
            'length':
            trigger_separation - station.pulsar.inter_element_spacing(),
            'phase': 90,
            'amplitude': amplitude,
            'pulse_delay': 0,
            'refpoint': 'simultaneous'
        }
        pulses.append(sin_pulse)
        channels.append(pulse_Q_channel)
    if pulse_I_channel is None and pulse_Q_channel is None:
        empty_pulse = {
            'pulse_type': 'SquarePulse',
            'channel': trigger_channel,
            'length':
            trigger_separation - station.pulsar.inter_element_spacing(),
            'amplitude': 0.,
            'pulse_delay': 0,
            'refpoint': 'simultaneous'
        }
        pulses.append(empty_pulse)
    el = multi_pulse_elt(0, station, pulses, trigger=True)
    seq = sequence.Sequence('Sideband_modulation_seq')
    seq.append(name='SSB_modulation_el', wfname=el.name, trigger_wait=True)
    if upload:
        station.pulsar.program_awgs(seq, el, channels=channels)
    return seq, [el]
예제 #25
0
def ramsey_seq_cont_drive(times,
                          pulse_pars,
                          RO_pars,
                          artificial_detuning=None,
                          cal_points=True,
                          upload=True,
                          return_seq=False,
                          **kw):
    '''
    Ramsey sequence for a single qubit using the tektronix.
    SSB_Drag pulse is used for driving, simple modualtion used for RO
    Input pars:
        times:               array of times between (start of) pulses (s)
        pulse_pars:          dict containing the pulse parameters
        RO_pars:             dict containing the RO parameters
        artificial_detuning: artificial_detuning (Hz) implemented using phase
        cal_points:          whether to use calibration points or not
    '''
    if np.any(times > 1e-3):
        logging.warning('The values in the times array might be too large.'
                        'The units should be seconds.')

    seq_name = 'Ramsey_sequence'
    seq = sequence.Sequence(seq_name)
    seg_list = []
    # First extract values from input, later overwrite when generating
    # waveforms
    pulses = get_pulse_dict_from_pars(pulse_pars)

    pulse_pars_x2 = deepcopy(pulses['X90'])

    DRAG_length = pulse_pars['nr_sigma'] * pulse_pars['sigma']
    cont_drive_ampl = 0.1 * pulse_pars['amplitude']
    X180_pulse = deepcopy(pulses['X180'])
    cos_pulse = {
        'pulse_type': 'CosPulse_gauss_rise',
        'channel': X180_pulse['I_channel'],
        'frequency': X180_pulse['mod_frequency'],
        'length': 0,
        'phase': X180_pulse['phi_skew'],
        'amplitude': cont_drive_ampl * X180_pulse['alpha'],
        'pulse_delay': 0,
        'ref_point': 'end'
    }
    sin_pulse = {
        'pulse_type': 'CosPulse_gauss_rise',
        'channel': X180_pulse['Q_channel'],
        'frequency': X180_pulse['mod_frequency'],
        'length': 0,
        'phase': 90,
        'amplitude': cont_drive_ampl * X180_pulse['alpha'],
        'pulse_delay': 0,
        'ref_point': 'simultaneous'
    }

    for i, tau in enumerate(times):

        if artificial_detuning is not None:
            Dphase = ((tau - times[0]) * artificial_detuning * 360) % 360
            pulse_pars_x2['phase'] = Dphase

        if cal_points and (i == (len(times) - 4) or i == (len(times) - 3)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['I'], RO_pars])
        elif cal_points and (i == (len(times) - 2) or i == (len(times) - 1)):
            seg = segment.Segment('segment_{}'.format(i),
                                  [pulses['X180'], RO_pars])
        else:
            X90_separation = tau - DRAG_length
            if X90_separation > 0:
                pulse_pars_x2['ref_point'] = 'end'
                cos_pls1 = deepcopy(cos_pulse)
                sin_pls1 = deepcopy(sin_pulse)
                cos_pls1['length'] = X90_separation / 2
                sin_pls1['length'] = X90_separation / 2
                cos_pls2 = deepcopy(cos_pls1)
                sin_pls2 = deepcopy(sin_pls1)
                cos_pls2['amplitude'] = -cos_pls1['amplitude']
                cos_pls2['pulse_type'] = 'CosPulse_gauss_fall'
                sin_pls2['amplitude'] = -sin_pls1['amplitude']
                sin_pls2['pulse_type'] = 'CosPulse_gauss_fall'

                pulse_dict_list = [
                    pulses['X90'], cos_pls1, sin_pls1, cos_pls2, sin_pls2,
                    pulse_pars_x2, RO_pars
                ]
            else:
                pulse_pars_x2['ref_point'] = 'start'
                pulse_pars_x2['pulse_delay'] = tau
                pulse_dict_list = [pulses['X90'], pulse_pars_x2, RO_pars]

            seg = segment.Segment('segment_{}'.format(i), pulse_dict_list)

        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