def HahnEcho(qubit, pulseSpacings, calRepeats=2, showPlot=False): """ A single pulse Hahn echo. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) pulseSpacings : pulse spacings to sweep over; the t in 90-t-180-t-180 (iterable) calRepeats : how many times to repeat calibration scalings (default 2) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqs = [ [X90(qubit), Id(qubit, t), X(qubit), Id(qubit,t), X90(qubit), MEAS(qubit)] for t in pulseSpacings] #Tack on the calibration scalings seqs += create_cal_seqs((qubit,), calRepeats) fileNames = compile_to_hardware(seqs, 'Echo/Echo') print(fileNames) if showPlot: plotWin = plot_pulse_files(fileNames) return plotWin
def HahnEcho(qubit, pulseSpacings, periods = 0, calRepeats=2, showPlot=False): """ A single pulse Hahn echo with variable phase of second pi/2 pulse. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) pulseSpacings : pulse spacings to sweep over; the t in 90-t-180-t-180 (iterable) periods: number of artificial oscillations calRepeats : how many times to repeat calibration scalings (default 2) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqs=[]; for k in range(len(pulseSpacings)): seqs.append([X90(qubit), Id(qubit, pulseSpacings[k]), Y(qubit), Id(qubit,pulseSpacings[k]), \ U90(qubit,phase=2*pi*periods/len(pulseSpacings)*k), MEAS(qubit)]) #Tack on the calibration scalings seqs += create_cal_seqs((qubit,), calRepeats) fileNames = compile_to_hardware(seqs, 'Echo/Echo') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def CPMG(qubit, numPulses, pulseSpacing, calRepeats=2, showPlot=False): """ CPMG pulse train with fixed pulse spacing. Note this pulse spacing is centre to centre, i.e. it accounts for the pulse width Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) numPulses : number of 180 pulses; should be even (iterable) pulseSpacing : spacing between the 180's (seconds) calRepeats : how many times to repeat calibration scalings (default 2) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ #First setup the t-180-t block CPMGBlock = [Id(qubit, (pulseSpacing-qubit.pulseParams['length'])/2), Y(qubit), Id(qubit, (pulseSpacing-qubit.pulseParams['length'])/2)] seqs = [[X90(qubit)] + CPMGBlock*rep + [X90(qubit), MEAS(qubit)] for rep in numPulses] #Tack on the calibration scalings seqs += create_cal_seqs((qubit,), calRepeats) fileNames = compile_to_hardware(seqs, 'CPMG/CPMG') print(fileNames) if showPlot: plotWin = plot_pulse_files(fileNames) return plotWin
def PiRabi(controlQ, targetQ, CRchan, lengths, riseFall=40e-9, amp=1, phase=0, calRepeats=2, showPlot=False): """ Variable length CX experiment. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) CRchan: logical channel for the cross-resonance pulse (LogicalChannel) lengths : pulse lengths of the CR pulse to sweep over (iterable) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqs = [[Id(controlQ)] + flat_top_gaussian(CRchan, riseFall, amp=amp, phase=phase, length=l) \ + [MEAS(targetQ)*MEAS(controlQ)] for l in lengths]+[[X(controlQ)] + flat_top_gaussian(CRchan, riseFall, amp=amp, phase=phase, length=l)\ + [X(controlQ), MEAS(targetQ)*MEAS(controlQ)] for l in lengths] + create_cal_seqs([targetQ,controlQ], calRepeats, measChans=(targetQ,controlQ)) fileNames = compile_to_hardware(seqs, 'PiRabi/PiRabi') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def SingleQubitRB_AC(qubit, seqs, showPlot=False): """ Single qubit randomized benchmarking using atomic Clifford pulses. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) seqFile : file containing sequence strings showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqsBis = [] for seq in seqs: seqsBis.append([AC(qubit, c) for c in seq]) #Add the measurement to all sequences for seq in seqsBis: seq.append(MEAS(qubit)) #Tack on the calibration sequences seqsBis += create_cal_seqs((qubit,), 2) fileNames = compile_to_hardware(seqsBis, 'RB/RB') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def RabiAmp_TwoQubits(qubit1, qubit2, amps, amps2, phase=0, showPlot=False, meas=[1,1],docals=False): """ Variable amplitude Rabi nutation experiment for up to two qubits, with measurement on both. Need to be extended to arbitrary number of qubits Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) amps : pulse amplitudes to sweep over for qubit 1(iterable) amps2: pulse amplitudes to sweep over for qubit 2(iterable, same index) phase : phase of the pulses (radians) showPlot : whether to plot (boolean) meas: list of 1/0 for measurement on/off Returns ------- plotHandle : handle to plot window to prevent destruction """ meas1 = MEAS(qubit1) if meas[0]==1 else Id(qubit1) meas2 = MEAS(qubit2) if meas[1]==1 else Id(qubit2) seqs = [[Utheta(qubit1, amp=amp, phase=phase)*Utheta(qubit2, amp=amp2,phase=phase), meas1*meas2] for (amp,amp2) in zip(amps,amps2)] if docals: seqs += create_cal_seqs((qubit1,qubit2), 2, measChans=(qubit1,qubit2)) fileNames = compile_to_hardware(seqs, 'Rabi/Rabi') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def SingleQubitRB_AC(qubit, seqs, showPlot=False): """ Single qubit randomized benchmarking using atomic Clifford pulses. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) seqFile : file containing sequence strings showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqsBis = [] for seq in seqs: seqsBis.append([AC(qubit, c) for c in seq]) #Add the measurement to all sequences for seq in seqsBis: seq.append(MEAS(qubit)) #Tack on the calibration sequences seqsBis += create_cal_seqs((qubit, ), 2) fileNames = compile_to_hardware(seqsBis, 'RB/RB') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def CPMG(qubit, numPulses, pulseSpacing, calRepeats=2, showPlot=False): """ CPMG pulse train with fixed pulse spacing. Note this pulse spacing is centre to centre, i.e. it accounts for the pulse width Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) numPulses : number of 180 pulses; should be even (iterable) pulseSpacing : spacing between the 180's (seconds) calRepeats : how many times to repeat calibration scalings (default 2) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ #First setup the t-180-t block CPMGBlock = [ Id(qubit, (pulseSpacing - qubit.pulseParams['length']) / 2), Y(qubit), Id(qubit, (pulseSpacing - qubit.pulseParams['length']) / 2) ] seqs = [[X90(qubit)] + CPMGBlock * rep + [X90(qubit), MEAS(qubit)] for rep in numPulses] #Tack on the calibration scalings seqs += create_cal_seqs((qubit, ), calRepeats) fileNames = compile_to_hardware(seqs, 'CPMG/CPMG') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def TwoQubitRB(q1, q2, CR, seqs, showPlot=False, suffix=""): """ Two qubit randomized benchmarking using 90 and 180 single qubit generators and ZX90 Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) seqs : list of lists of Clifford group integers showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqsBis = [] for seq in seqs: seqsBis.append( reduce(operator.add, [clifford_seq(c, q1, q2, CR) for c in seq])) #Add the measurement to all sequences for seq in seqsBis: seq.append(MEAS(q1, q2)) #Tack on the calibration sequences seqsBis += create_cal_seqs((q1, q2), 2) fileNames = compile_to_hardware(seqsBis, 'RB/RB', suffix=suffix) print(fileNames) if showPlot: plot_pulse_files(fileNames)
def EchoCRPhase(controlQ, targetQ, phases, riseFall=40e-9, amp=1, length=100e-9, calRepeats=2, showPlot=False): """ Variable phase CX experiment, with echo pulse sandwiched between two CR opposite-phase pulses. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) CRchan: logical channel for the cross-resonance pulse (LogicalChannel) phases : pulse phases of the CR pulse to sweep over (iterable) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqs = [[Id(controlQ)] + echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall) + [X90(targetQ)*Id(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ for ph in phases]+[[X(controlQ)] + echoCR(controlQ, targetQ, length=length, phase= ph, riseFall = riseFall) + [X90(targetQ)*X(controlQ), MEAS(targetQ)*MEAS(controlQ)]\ for ph in phases]+create_cal_seqs((targetQ,controlQ), calRepeats, measChans=(targetQ,controlQ)) fileNames = compile_to_hardware(seqs, 'EchoCR/EchoCR') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def InversionRecovery(qubit, delays, showPlot=False, calRepeats=2): """ Inversion recovery experiment to measure qubit T1 Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) delays : delays after inversion before measurement (iterable; seconds) showPlot : whether to plot (boolean) calRepeats : how many repetitions of calibration pulses (int) Returns ------- plotHandle : handle to plot window to prevent destruction """ #Create the basic sequences seqs = [[X(qubit), Id(qubit, d), MEAS(qubit)] for d in delays] #Tack on the calibration scalings seqs += create_cal_seqs((qubit,), calRepeats) fileNames = compile_to_hardware(seqs, 'T1/T1') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def TwoQubitRB(q1, q2, CR, seqs, showPlot=False, suffix=""): """ Two qubit randomized benchmarking using 90 and 180 single qubit generators and ZX90 Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) seqs : list of lists of Clifford group integers showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqsBis = [] for seq in seqs: seqsBis.append(reduce(operator.add, [clifford_seq(c, q1, q2, CR) for c in seq])) #Add the measurement to all sequences for seq in seqsBis: seq.append(MEAS(q1, q2)) #Tack on the calibration sequences seqsBis += create_cal_seqs((q1,q2), 2) fileNames = compile_to_hardware(seqsBis, 'RB/RB', suffix=suffix) print(fileNames) if showPlot: plot_pulse_files(fileNames)
def Swap(qubit, mqubit, delays, showPlot=False): """ Variable amplitude Rabi nutation experiment. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) amps : pulse amplitudes to sweep over (iterable) phase : phase of the pulse (radians) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqs = [[X(qubit), X(mqubit), Id(mqubit, d), MEAS(mqubit) * MEAS(qubit)] for d in delays] + create_cal_seqs( (mqubit, qubit), 2, measChans=(mqubit, qubit)) fileNames = compile_to_hardware(seqs, 'Rabi/Rabi') print(fileNames) if showPlot: plotWin = plot_pulse_files(fileNames) return plotWin
def Ramsey(qubit, pulseSpacings, TPPIFreq=0, showPlot=False, calRepeats=2): """ Variable pulse spacing Ramsey (pi/2 - tau - pi/2) with optional TPPI. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) pulseSpacings : pulse spacings (iterable; seconds) TPPIFreq : frequency for TPPI phase updates of second Ramsey pulse (Hz) showPlot : whether to plot (boolean) calRepeats : how many repetitions of calibration pulses (int) Returns ------- plotHandle : handle to plot window to prevent destruction """ #Create the phases for the TPPI phases = 2*pi*TPPIFreq*pulseSpacings #Create the basic Ramsey sequence seqs = [[X90(qubit), Id(qubit, d), U90(qubit, phase=phase), MEAS(qubit)] for d,phase in zip(pulseSpacings, phases)] #Tack on the calibration scalings seqs += create_cal_seqs((qubit,), calRepeats) fileNames = compile_to_hardware(seqs, 'Ramsey/Ramsey') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def HahnEcho(qubit, pulseSpacings, periods=0, calRepeats=2, showPlot=False): """ A single pulse Hahn echo with variable phase of second pi/2 pulse. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) pulseSpacings : pulse spacings to sweep over; the t in 90-t-180-t-180 (iterable) periods: number of artificial oscillations calRepeats : how many times to repeat calibration scalings (default 2) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqs = [] for k in range(len(pulseSpacings)): seqs.append([X90(qubit), Id(qubit, pulseSpacings[k]), Y(qubit), Id(qubit,pulseSpacings[k]), \ U90(qubit,phase=2*pi*periods/len(pulseSpacings)*k), MEAS(qubit)]) #Tack on the calibration scalings seqs += create_cal_seqs((qubit, ), calRepeats) fileNames = compile_to_hardware(seqs, 'Echo/Echo') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def RabiAmp_TwoQubits(qubit1, qubit2, amps, amps2, phase=0, showPlot=False, meas=[1, 1], docals=False): """ Variable amplitude Rabi nutation experiment for up to two qubits, with measurement on both. Need to be extended to arbitrary number of qubits Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) amps : pulse amplitudes to sweep over for qubit 1(iterable) amps2: pulse amplitudes to sweep over for qubit 2(iterable, same index) phase : phase of the pulses (radians) showPlot : whether to plot (boolean) meas: list of 1/0 for measurement on/off Returns ------- plotHandle : handle to plot window to prevent destruction """ meas1 = MEAS(qubit1) if meas[0] == 1 else Id(qubit1) meas2 = MEAS(qubit2) if meas[1] == 1 else Id(qubit2) seqs = [[ Utheta(qubit1, amp=amp, phase=phase) * Utheta(qubit2, amp=amp2, phase=phase), meas1 * meas2 ] for (amp, amp2) in zip(amps, amps2)] if docals: seqs += create_cal_seqs((qubit1, qubit2), 2, measChans=(qubit1, qubit2)) fileNames = compile_to_hardware(seqs, 'Rabi/Rabi') print(fileNames) if showPlot: plot_pulse_files(fileNames)
def PiRabi(controlQ, targetQ, lengths, riseFall=40e-9, amp=1, phase=0, calRepeats=2, showPlot=False): """ Variable length CX experiment. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ: logical channel for the target qubit (LogicalChannel) lengths : pulse lengths of the CR pulse to sweep over (iterable) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ CRchan = EdgeFactory(controlQ, targetQ) seqs = ( [ [ Id(controlQ), flat_top_gaussian(CRchan, riseFall, amp=amp, phase=phase, length=l), MEAS(targetQ) * MEAS(controlQ), ] for l in lengths ] + [ [ X(controlQ), flat_top_gaussian(CRchan, riseFall, amp=amp, phase=phase, length=l), X(controlQ), MEAS(targetQ) * MEAS(controlQ), ] for l in lengths ] + create_cal_seqs([targetQ, controlQ], calRepeats, measChans=(targetQ, controlQ)) ) fileNames = compile_to_hardware(seqs, "PiRabi/PiRabi") print(fileNames) if showPlot: plot_pulse_files(fileNames)
def EchoCRPhase(controlQ, targetQ, phases, riseFall=40e-9, amp=1, length=100e-9, calRepeats=2, showPlot=False): """ Variable phase CX experiment, with echo pulse sandwiched between two CR opposite-phase pulses. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) CRchan: logical channel for the cross-resonance pulse (LogicalChannel) phases : pulse phases of the CR pulse to sweep over (iterable) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqs = ( [ [Id(controlQ)] + echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall) + [X90(targetQ) * Id(controlQ), MEAS(targetQ) * MEAS(controlQ)] for ph in phases ] + [ [X(controlQ)] + echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall) + [X90(targetQ) * X(controlQ), MEAS(targetQ) * MEAS(controlQ)] for ph in phases ] + create_cal_seqs((targetQ, controlQ), calRepeats, measChans=(targetQ, controlQ)) ) fileNames = compile_to_hardware(seqs, "EchoCR/EchoCR") print(fileNames) if showPlot: plot_pulse_files(fileNames)
def Swap(qubit, mqubit, delays, showPlot=False): """ Variable amplitude Rabi nutation experiment. Parameters ---------- qubit : logical channel to implement sequence (LogicalChannel) amps : pulse amplitudes to sweep over (iterable) phase : phase of the pulse (radians) showPlot : whether to plot (boolean) Returns ------- plotHandle : handle to plot window to prevent destruction """ seqs = [[X(qubit), X(mqubit), Id(mqubit, d), MEAS(mqubit)*MEAS(qubit)] for d in delays] + create_cal_seqs((mqubit,qubit), 2, measChans=(mqubit,qubit)) fileNames = compile_to_hardware(seqs, 'Rabi/Rabi') print(fileNames) if showPlot: plotWin = plot_pulse_files(fileNames) return plotWin