def PSB_read_latched(segment, gates, t_ramp, t_read, p_0, p_1, p_2, disable_trigger=False): ''' pulse able to perform a psb readout Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : plunger gate names t_ramp (double) : time to linearly ramp trought the anticrossing t_read (double) : readout time p_0 (tuple <double>) : starting point p_1 (tuple <double>) : point after the anticrossing p_2 (tuple <double>) : effective point where the averaging should happen disable_trigger (bool) : disable triggerig for digitizer, only for debuggig. ''' # jump close to (1,1) -- (2,0) wait 100 ns add_block(segment, 100, gates, p_0) # pulse towards the window and stay for the measurment time add_ramp(segment, t_ramp, gates, p_0, p_1) add_ramp(segment, 10, gates, p_1, p_2) if disable_trigger == False: getattr(segment, gates[0]).add_HVI_marker("dig_trigger_1") getattr(segment, gates[0]).add_HVI_variable("t_measure", t_read) add_block(segment, t_read, gates, p_2)
def CROT_basic(segment, gates, v_exchange_pulse_off, v_exchange_pulse_on, gate_spec, t_ramp, padding=2): ''' basic cphase, with a linear ramp Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : gates to be pulses for this gate. barrier_gate (str) : barrier to pulse (for the ac) v_exchange_pulse (double) : voltage to pulse to t_gate (double) : total time of the gate not inclusing the ramps t_ramp (double) : ramp time ''' add_ramp(segment, t_ramp, gates, v_exchange_pulse_off, v_exchange_pulse_on) add_block(segment, padding, gates, v_exchange_pulse_on) for gate, level in zip(gates, v_exchange_pulse_on): getattr(segment, gate).add_block(0, gate_spec.t_pulse + gate_spec.padding * 2, level) gate_spec.add(segment, reset=False) segment.reset_time() add_block(segment, padding, gates, v_exchange_pulse_on) add_ramp(segment, t_ramp, gates, v_exchange_pulse_on, v_exchange_pulse_off)
def PSB_read_tc_ctrl(segment, gates, t_ramp, t_read, p_0, p_1, p_2, nth_readout, disable_trigger=False): ''' pulse able to perform a psb readout, the tunnelcoupling is lowered at the end to make the pulse robust against T1 effects. Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : plunger gate names t_ramp (double) : time to linearly ramp trought the anticrossing t_read (double) : readout time p_0 (tuple <double>) : starting point p_1 (tuple<double>) : point after the anticrossing, for readout, when the tunnel coupling is on p_2 (tuple<double>) : point after the anticrossing, for readout, when the tunnel coupling oig odff disable_trigger (bool) : disable triggerig for digitizer, only for debuggig. ''' # pulse towards the window and stay for the measurment time add_ramp(segment, t_ramp, gates, p_0, p_1) add_ramp(segment, 10, gates, p_1, p_2) if disable_trigger == False: getattr(segment, gates[0]).add_HVI_marker("dig_trigger_{}".format(int(nth_readout))) getattr(segment, gates[0]).add_HVI_variable("t_measure", t_read) add_block(segment, t_read, gates, p_2) add_ramp(segment, 10, gates, p_2, p_1) add_ramp(segment, t_ramp, gates, p_1, p_0)
def pulse_in_out(segment, gates, t_ramp, t_wait, p_0, p_1, p_2, **kwargs): ''' pulse sequence to go adiabatically trough an interdot. The standard time to go from p_0 to p_1 and p_2 to p_3 is 100ns Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : plunger gate names t_ramp (double) : time to linearly ramp trought the anticrossing t_wait (double) : time to wait at p1 p_0 (tuple <double>) : starting point p_1 (tuple<double>) : point where to wait ''' # move towards anti-crossing, standaard 100ns add_ramp(segment, t_ramp, gates, p_0, p_1) add_ramp(segment, t_ramp, gates, p_1, p_2) # go though the anti-crossing add_block(segment, t_wait, gates, p_2) # move towards anti-crossing, standaard 100ns add_ramp(segment, t_ramp, gates, p_2, p_1) # move towards anti-crossing, standaard 100ns add_ramp(segment, t_ramp, gates, p_1, p_0)
def iswap_basic(segment, gates, barrier_gate, v_exchange_pulse_off, v_exchange_pulse_on, v_ac, f_ac, t_gate, t_ramp, padding=2): ''' basic iSWAP, with a linear ramp Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : gates to be pulses for this gate. barrier_gate (str) : barrier to pulse (for the ac) v_exchange_pulse (double) : voltage to pulse to t_gate (double) : total time of the gate not inclusing the ramps t_ramp (double) : ramp time ''' add_ramp(segment, t_ramp, gates, v_exchange_pulse_off, v_exchange_pulse_on) add_block(segment, padding, gates, v_exchange_pulse_on) for gate, level in zip(gates, v_exchange_pulse_on): getattr(segment, gate).add_block(0, t_gate, level) getattr(segment, barrier_gate).add_sin(0, t_gate, v_ac, f_ac) segment.reset_time() add_block(segment, padding, gates, v_exchange_pulse_on) add_ramp(segment, t_ramp, gates, v_exchange_pulse_on, v_exchange_pulse_off)
def wait(segment, gates, t_wait, p_0, reset_time=True, **kwargs): ''' wait at p_0 for t_wait Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : plunger gate names t_wait (double) : time to wait at p_0 p_0 (tuple <double>) : point where to wait at ''' add_block(segment, t_wait, gates, p_0, reset_time)
def pulse_intra(segment, gates, t_wait, t_ramp, p_0, p_1, **kwargs): ''' pulse over a transition line of 1 dot (e.g. N=0->N=1). first wait at p_0, the adiabatically ramp to p_1 Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : plunger gate names t_wait (double) : time wait at p_0 p_0 (tuple <double>) : starting point p_1 (tuple<double>) : end point after the ramp ''' # wait a bit at the first point, e.g. make sure you are in the right charge state add_block(segment, t_wait, gates, p_0) # ramp slowly to where you want to be. add_ramp(segment, t_ramp, gates, p_0, p_1)
def PSB_read_multi(segment, gates, t_ramp, t_read, p_0, p_1, nth_readout=0, unmute=None, disable_trigger=False): ''' pulse able to perform a psb readout Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : plunger gate names t_ramp (double) : time to linearly ramp trought the anticrossing t_read (double) : readout time p_0 (tuple <double>) : starting point p_1 (tuple<double>) : point after the anticrossing, where the readout should happen. disable_trigger (bool) : disable triggerig for digitizer, only for debuggig. ''' # pulse towards the window and stay for the measurment time add_ramp(segment, t_ramp, gates, p_0, p_1) if unmute is not None: getattr(segment, unmute).add_marker(0, t_read) if disable_trigger == False: getattr(segment, gates[0]).add_HVI_marker("dig_trigger_{}".format(int(nth_readout))) getattr(segment, gates[0]).add_HVI_variable("t_measure", t_read) add_block(segment, t_read, gates, p_1) add_ramp(segment, t_ramp, gates, p_1, p_0)
def elzerman_read_multi(segment, gates, t_read, p_readout, nth_readout=0, disable_trigger=False, **kwargs): ''' pulse able to perform a psb readout Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : plunger gate names t_read (double) : readout time p_readout (tuple <double>) : point where to readout disable_trigger (bool) : disable triggerig for digitizer, only for debuggig. ''' if disable_trigger == False: getattr(segment, gates[0]).add_HVI_marker("dig_wait_{}".format( int(nth_readout))) getattr(segment, gates[0]).add_HVI_variable("t_measure", t_read) add_block(segment, t_read, gates, p_readout)
def elzerman_basic(segment, gates, t_init, t_ramp, t_load, t_read, p_0, p_1, p_2, p_3, p_4, disable_trigger=False, **kwargs): ''' pulse able to perform a psb readout Args: segment (segment_container) : segment to which to add this stuff gates (tuple<str>) : plunger gate names t_init (double) : initialisation time to eject electron t_ramp (double) : time to ramp t_load (double) : time to wait at the load stage t_read (double) : readout time p_0 (tuple <double>) : init point p_1 (tuple <double>) : ramp start from N=0 to N=1 p_2 (tuple <double>) : ramp end from N=0 to N=1 p_3 (tuple <double>) : operating point p_4 (tuple <double>) : point where to readout disable_trigger (bool) : disable triggerig for digitizer, only for debuggig. ''' # init add_block(segment, t_init, gates, p_0) # pulse towards the window and stay for the measurment time add_ramp(segment, t_ramp, gates, p_1, p_2) add_block(segment, t_load, gates, p_3) if disable_trigger == False: getattr(segment, gates[0]).add_HVI_marker("dig_wait") getattr(segment, gates[0]).add_HVI_variable("t_measure", t_read) add_block(segment, t_read, gates, p_4)
from pulse_templates.coherent_control.single_qubit_gates.standard_set import single_qubit_std_set from pulse_templates.coherent_control.single_qubit_gates.single_qubit_gates import single_qubit_gate_spec from pulse_templates.elzerman_pulses.basic_elzerman_pulse import elzerman_read pulse = get_demo_lib('quad') INIT = pulse.mk_segment() MANIP = pulse.mk_segment() READ = pulse.mk_segment() # assume 1QD -- elzerman init t_init = 50e3 gates = ('vP1', ) p_0 = (200, ) add_block(INIT, t_init, gates, p_0) #done. # add single qubit gates in manip # add default dc levels MANIP.vP1 += 20 # define a set xpi2 = single_qubit_gate_spec('qubit1_MW', 1.1e8, 1000, 120, padding=2) xpi = single_qubit_gate_spec('qubit1_MW', 1.1e8, 2000, 120, padding=2) ss_set = single_qubit_std_set() ss_set.X = xpi2 ss_set.X2 = xpi
def iswap(segment, gates, iswap_angle, phase, J_max, delta_B, J_to_voltage_relation, f_res_to_J_relation, padding=5): ''' iSWAP gate for spins, this is basically a modulated verions of the cphase (convert to SWAP by running iSWAP and then CPHASE) -- this function does not guarantee that the accumalted ZZ phase is correct Args: segment (segment_container) : segment to which to add this stuff gates (list<str>) : list of gates involved in the cphase gate (relations of J and f_res need to be provided for each gate) iswap_angle (double) : angle to rotate with the iSWAP gate phase (double) : starting phase of the iswap gate (important if you sqrt(iSWAP)) J_max (double) : maximum amount of J that should be reached delta_B (double) : frequency difference between the qubits J_to_voltage_relation (list<func>) : function that returns the voltages to be applied for a certain amount of J (same order as the gates) f_res_to_J_relation (func) : function that returns the resonance frequency for J padding (int) : padding to add around the swap gate. ''' if isinstance(J_max, loop_obj): raise ValueError( 'J_max is a loop object, this is currently not supported for this function' ) if isinstance(delta_B, loop_obj): raise ValueError( 'delta_B is a loop object, this is currently not supported for this function' ) if len(gates) != len(J_to_voltage_relation): raise ValueError( f'found {len(gates)} gates and {len(len(J_to_voltage_relation))} J_to_voltage_relation\'s, something must be wrong here.' ) if isinstance(iswap_angle, loop_obj) and isinstance(phase, loop_obj): raise ValueError( 'No implementation yet to sweep iSWAP angle and phase.') if isinstance(iswap_angle, loop_obj): t_gate = copy.copy(iswap_angle) amplitudes = tuple() pulse_templates = tuple() for i in range(len(gates)): functions = copy.copy(iswap_angle) functions.data = np.empty(iswap_angle.data.shape, dtype=object) for j in range(t_gate.data.size): func, duration = return_creation_fuction( iswap_angle.data[j], phase, J_max, delta_B, J_to_voltage_relation[i], f_res_to_J_relation) t_gate.data[j] = duration functions.data[j] = func pulse_templates += (functions, ) amplitudes += (1, ) elif isinstance(phase, loop_obj): amplitudes = tuple() pulse_templates = tuple() for i in range(len(gates)): functions = copy.copy(phase) functions.data = np.empty(phase.data.shape, dtype=object) for j in range(phase.data.size): func, duration = return_creation_fuction( iswap_angle, phase.data[j], J_max, delta_B, J_to_voltage_relation[i], f_res_to_J_relation) t_gate = duration functions.data[j] = func pulse_templates += (functions, ) amplitudes += (1, ) else: t_gate = 0 amplitudes = tuple() pulse_templates = tuple() for i in range(len(gates)): func, duration = return_creation_fuction(iswap_angle, phase, J_max, delta_B, J_to_voltage_relation[i], f_res_to_J_relation) t_gate = duration amplitudes += (1, ) pulse_templates += (func, ) add_block(segment, padding, gates, tuple([0] * len(gates))) add_pulse_template(segment, t_gate, gates, amplitudes, pulse_templates) add_block(segment, padding, gates, tuple([0] * len(gates)))
def iswap_cal(segment, gates, J_value, J_excitation, f_excitation, angle, J_to_voltage_relation, padding=5): ''' Function to help with the calibration of iswap gates. A ramp is done to the target J, then a excitation with a desired amplitude is provided. Args: segment (segment_container) : segment to which to add this stuff gates (list<str>) : list of gates involved in the cphase gate (relations of J and f_res need to be provided for each gate) J_value (double) : value of J to go for (Hz) J_excitation (double) : value of J to excite with (Hz) (e.g. 500e3) f_excitation (double) : frequency of the J excitation (Hz) J_to_voltage_relation (list<func>) : function that returns the voltages to be applied for a certain amount of J (same order as the gates) padding (int) : padding to be added in ns around this experiment ''' t_gate = 0 amplitudes = tuple() pulse_templates = tuple() loop_dim = np.zeros(10, dtype=np.int) units = dict() labels = dict() setvals = dict() for i in [ J_value, J_excitation, f_excitation, angle, J_to_voltage_relation ]: if isinstance(i, loop_obj): if -1 in i.axis: raise ValueError( f'The sweep axis must be set for this template.') loop_dim[i.axis] = i.shape for j in i.axis: units[j] = i.units[0] #this housld be more deterministic labels[j] = i.labels[0] setvals[j] = i.setvals[0] if any(loop_dim != 0): loop_axis = np.where(loop_dim != 0)[0] shape = loop_dim[loop_axis] u, l, s = [], [], [] for i in sorted(units.keys()): u.append(units[i]) l.append(labels[i]) s.append(setvals[i]) J_value = to_loop_obj(J_value, shape, loop_axis, l, u, s) J_excitation = to_loop_obj(J_excitation, shape, loop_axis, l, u, s) f_excitation = to_loop_obj(f_excitation, shape, loop_axis, l, u, s) angle = to_loop_obj(angle, shape, loop_axis, l, u, s) amplitudes = tuple() pulse_templates = tuple() for i in range(len(gates)): t_gate = to_loop_obj(0, shape, loop_axis, l, u, s) functions = to_loop_obj(object(), shape, loop_axis, l, u, s) functions.data = np.empty(f_excitation.data.shape, dtype=object) for j in range(t_gate.data.size): idx = np.unravel_index(j, t_gate.data.shape) func, duration = return_creation_fuction_iswap_cal( J_value.data[idx], J_excitation.data[idx], f_excitation.data[idx], angle.data[idx], J_to_voltage_relation[i]) t_gate.data[idx] = duration functions.data[idx] = func pulse_templates += (functions, ) amplitudes += (1, ) else: for i in range(len(gates)): func, duration = return_creation_fuction_iswap_cal( J_value, J_excitation, f_excitation, angle, J_to_voltage_relation[i]) t_gate = duration amplitudes += (1, ) pulse_templates += (func, ) add_block(segment, padding, gates, tuple([0] * len(gates))) add_pulse_template(segment, t_gate, gates, amplitudes, pulse_templates) add_block(segment, padding, gates, tuple([0] * len(gates)))