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
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
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
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
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
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
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
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
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
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
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
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
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]
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