def flipflop_seqs(dragScaling, maxNumFFs, qubit: qreg): """ Helper function to create a list of sequences with a specified drag parameter. """ # FIXME: cause qubit is a placeholder, can't access pulse_params # qubit.pulse_params['dragScaling'] = dragScaling for rep in range(maxNumFFs): init(qubit) X90(qubit, dragScaling=dragScaling) # FIXME: Original used [X90] + [X90, X90m]... is this right? for _ in range(rep): X90(qubit, dragScaling=dragScaling) X90m(qubi, dragScaling=dragScaling) Y90(qubit, dragScaling=dragScaling) MEAS(qubit) # FIXME: Need original dragScaling?
def addFFSeqs(dragParam, maxNumFFs, qubit): ffs = [] for rep in range(maxNumFFs): ffs += [ qwait(channels=(qubit, )), X90(qubit, dragScaling=dragParam) ] for _ in range(rep): ffs += [ X90(qubit, dragScaling=dragParam), X90m(qubit, dragScaling=dragParam) ] ffs += [Y90(qubit, dragScaling=dragParam), MEAS(qubit)] return ffs
def flipflop_seqs(dragScaling): """ Helper function to create a list of sequences with a specified drag parameter. """ qubit.pulse_params['dragScaling'] = dragScaling seqs = [] for rep in range(maxNumFFs): seq = [] seq.append(X90(qubit)) # FIXME: Origin used [X90] + [X90, X90m]... is this right? for _ in range(rep): seq.append(X90(qubit)) seq.append(X90m(qubit)) seq.append(Y90(qubit)) seqs.append(seq) return seqs
def test_Ramsey(self): q = QubitFactory('q1') qr = QRegister('q1') delays = np.arange(100e-9, 10e-6, 100e-9) TPPIFreq = 1e6 calRepeats = 2 expectedseq = [] # Create the phases for the TPPI phases = 2 * pi * TPPIFreq * delays # Create the basic Ramsey sequence for d, phase in zip(delays, phases): expectedseq += [ qwait(channels=(q, )), X90(q), Id(q, d), U90(q, phase=phase), MEAS(q) ] # Add calibration cal = get_cal_seqs_1qubit(q, calRepeats) expectedseq += cal expectedseq = testable_sequence(expectedseq) resFunction = compile_function( "src/python/qgl2/basic_sequences/T1T2.py", "Ramsey", (qr, delays, TPPIFreq, calRepeats)) seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expectedseq)
def test_HahnEcho(self): q = QubitFactory('q1') qr = QRegister('q1') steps = 11 pulseSpacings = np.linspace(0, 5e-6, steps) periods = 0 calRepeats = 2 expectedseq = [] for k in range(len(pulseSpacings)): expectedseq += [ qwait(channels=(q, )), X90(q), Id(q, pulseSpacings[k]), Y(q), Id(q, pulseSpacings[k]), U90(q, phase=2 * pi * periods / len(pulseSpacings) * k), MEAS(q) ] # Add calibration cal = get_cal_seqs_1qubit(q, calRepeats) expectedseq += cal expectedseq = testable_sequence(expectedseq) resFunction = compile_function( "src/python/qgl2/basic_sequences/Decoupling.py", "HahnEcho", (qr, pulseSpacings, periods, calRepeats)) seqs = resFunction() seqs = testable_sequence(seqs) # import ipdb; ipdb.set_trace() assertPulseSequenceEqual(self, seqs, expectedseq)
def Ramseyq1(qubit: qreg, pulseSpacings, TPPIFreq=0, showPlot=False, calRepeats=2, suffix=False): """ 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) """ # Original: # # 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'+('_'+qubit.label)*suffix+'/Ramsey'+('_'+qubit.label)*suffix) # print(fileNames) # if showPlot: # plot_pulse_files(fileNames) # Create the phases for the TPPI phases = 2*pi*TPPIFreq*pulseSpacings # Creating sequences that look like this: # [['X90', 'Id', 'U90', 'M'], ['X90', 'Id', 'U90', 'M']] # Create the basic Ramsey sequence seqs = [] for d,phase in zip(pulseSpacings, phases): seq = [] seq.append(X90(qubit)) seq.append(Id(qubit, d)) seq.append(U90(qubit, phase=phase)) seq.append(MEAS(qubit)) seqs.append(seq) # Tack on calibration # seqs = addCalibration(seqs, (qubit,), calRepeats) # Calculate label label = 'Ramsey'+('_'+qubit.label)*suffix fullLabel = label + '/' + label
def doRamsey(): q = QubitFactory('q1') TPPIFreq=1e6 # FIXME: QGL2 doesn't deal well with the call to np.arange pulseS = [ 1.00000000e-07, 2.00000000e-07, 3.00000000e-07, 4.00000000e-07, 5.00000000e-07, 6.00000000e-07, 7.00000000e-07, 8.00000000e-07, 9.00000000e-07, 1.00000000e-06, 1.10000000e-06, 1.20000000e-06, 1.30000000e-06, 1.40000000e-06, 1.50000000e-06, 1.60000000e-06, 1.70000000e-06, 1.80000000e-06, 1.90000000e-06, 2.00000000e-06, 2.10000000e-06, 2.20000000e-06, 2.30000000e-06, 2.40000000e-06, 2.50000000e-06, 2.60000000e-06, 2.70000000e-06, 2.80000000e-06, 2.90000000e-06, 3.00000000e-06, 3.10000000e-06, 3.20000000e-06, 3.30000000e-06, 3.40000000e-06, 3.50000000e-06, 3.60000000e-06, 3.70000000e-06, 3.80000000e-06, 3.90000000e-06, 4.00000000e-06, 4.10000000e-06, 4.20000000e-06, 4.30000000e-06, 4.40000000e-06, 4.50000000e-06, 4.60000000e-06, 4.70000000e-06, 4.80000000e-06, 4.90000000e-06, 5.00000000e-06, 5.10000000e-06, 5.20000000e-06, 5.30000000e-06, 5.40000000e-06, 5.50000000e-06, 5.60000000e-06, 5.70000000e-06, 5.80000000e-06, 5.90000000e-06, 6.00000000e-06, 6.10000000e-06, 6.20000000e-06, 6.30000000e-06, 6.40000000e-06, 6.50000000e-06, 6.60000000e-06, 6.70000000e-06, 6.80000000e-06, 6.90000000e-06, 7.00000000e-06, 7.10000000e-06, 7.20000000e-06, 7.30000000e-06, 7.40000000e-06, 7.50000000e-06, 7.60000000e-06, 7.70000000e-06, 7.80000000e-06, 7.90000000e-06, 8.00000000e-06, 8.10000000e-06, 8.20000000e-06, 8.30000000e-06, 8.40000000e-06, 8.50000000e-06, 8.60000000e-06, 8.70000000e-06, 8.80000000e-06, 8.90000000e-06, 9.00000000e-06, 9.10000000e-06, 9.20000000e-06, 9.30000000e-06, 9.40000000e-06, 9.50000000e-06, 9.60000000e-06, 9.70000000e-06, 9.80000000e-06, 9.90000000e-06] #pulseSpacings=np.arange(100e-9, 10e-6, 100e-9) # Create the phases for the TPPI phases = 2*pi*TPPIFreq*pulseS # Create the basic Ramsey sequence # FIXME: QGL2 doesn't deal well with this call to zip for d,phase in zip(pulseS, phases): init(q) X90(q) Id(q, d) U90(q, phase=phase) MEAS(q) # Tack on calibration create_cal_seqs((q,), calRepeats)
def test_CPMG(self): q = QubitFactory('q1') qr = QRegister('q1') # Create numPulses sequences numPulses = [0, 2, 4, 6] pulseSpacing = 500e-9 pulseSpacingDiff = pulseSpacing - q.pulse_params['length'] calRepeats = 2 def addt180t(q, pulseSpacingDiff, rep): t180t = [] for _ in range(rep): t180t += [ Id(q, pulseSpacingDiff / 2), Y(q), Id(q, pulseSpacingDiff / 2) ] return t180t expectedseq = [] for rep in numPulses: expectedseq += [qwait(channels=(q, )), X90(q)] expectedseq += addt180t(q, pulseSpacingDiff, rep) expectedseq += [X90(q), MEAS(q)] # Add calibration cal = get_cal_seqs_1qubit(q, calRepeats) expectedseq += cal expectedseq = testable_sequence(expectedseq) resFunction = compile_function( "src/python/qgl2/basic_sequences/Decoupling.py", "CPMG", (qr, numPulses, pulseSpacing, calRepeats)) seqs = resFunction() seqs = testable_sequence(seqs) assertPulseSequenceEqual(self, seqs, expectedseq)
def spam_seqs(angle, qubit: qreg, maxSpamBlocks=10): """ Helper function to create a list of sequences increasing SPAM blocks with a given angle. """ #SPAMBlock = [X(qubit), U(qubit, phase=pi/2+angle), X(qubit), U(qubit, phase=pi/2+angle)] #return [[Y90(qubit)] + SPAMBlock*rep + [X90(qubit)] for rep in range(maxSpamBlocks)] for rep in range(maxSpamBlocks): init(qubit) Y90(qubit) for _ in range(rep): X(qubit) U(qubit, phase=pi/2+angle) X(qubit) U(qubit, phase=pi/2+angle) X90(qubit) MEAS(qubit)
def spam_seqs(angle, q, maxSpamBlocks): thisseq = [] for rep in range(maxSpamBlocks): thisseq += [qwait(channels=(q, )), Y90(q)] innerseq = [] for _ in range(rep): innerseq += [ X(q), U(q, phase=pi / 2 + angle), X(q), U(q, phase=pi / 2 + angle) ] thisseq += innerseq thisseq += [X90(q), MEAS(q)] return thisseq
def spam_seqs(angle): """ Helper function to create a list of sequences increasing SPAM blocks with a given angle. """ #SPAMBlock = [X(qubit), U(qubit, phase=pi/2+angle), X(qubit), U(qubit, phase=pi/2+angle)] #return [[Y90(qubit)] + SPAMBlock*rep + [X90(qubit)] for rep in range(maxSpamBlocks)] seqs = [] for rep in range(maxSpamBlocks): seq = [] seq.append(Y90(qubit)) for _ in range(rep): seq.append(X(qubit)) seq.append(U(qubit, phase=pi/2+angle)) seq.append(X(qubit)) seq.append(U(qubit, phase=pi/2+angle)) seq.append(X90(qubit)) seqs.append(seq) return seqs
def testSingleQubitRB_AC(qubit, seqs, purit=False, add_cal=True): from QGL.PulsePrimitives import AC, MEAS, Id, Y90m, X90 from QGL.BasicSequences.helpers import create_cal_seqs from functools import reduce import operator seqsBis = [] op = [Id(qubit, length=0), Y90m(qubit), X90(qubit)] for ct in range(3 if purit else 1): for seq in seqs: seqsBis.append([AC(qubit, c) for c in seq]) # append tomography pulse to measure purity seqsBis[-1].append(op[ct]) # append measurement seqsBis[-1].append(MEAS(qubit)) # Tack on the calibration sequences if add_cals: seqsBis += create_cal_seqs((qubit, ), 2) return seqsBis
def testSingleQubitRB(qubit, rbseqs, purit=False, add_cal=True): from QGL.Cliffords import clifford_seq from QGL.BasicSequences.helpers import create_cal_seqs from functools import reduce import operator seqsBis = [] op = [Id(qubit, length=0), Y90m(qubit), X90(qubit)] for ct in range(3 if purit else 1): for seq in rbseqs: seqsBis.append( reduce(operator.add, [clifford_seq(c, qubit) for c in seq])) #append tomography pulse to measure purity seqsBis[-1].append(op[ct]) #append measurement seqsBis[-1].append(MEAS(qubit)) #Tack on the calibration sequences if add_cal: seqsBis += create_cal_seqs((qubit, ), 2) return seqsBis
def test_EchoCRPhase(self): controlQ = QubitFactory('q1') targetQ = QubitFactory('q2') cR = QRegister('q1') tR = QRegister('q2') phases = np.linspace(0, pi / 2, 11) riseFall = 40e-9 amp = 1 length = 100e-9 calRepeats = 2 canc_amp = 0 canc_phase = np.pi / 2 expected_seq = [] # Seq1 for p in phases: expected_seq += [ qwait(channels=(controlQ, targetQ)), Id(controlQ), echoCR(controlQ, targetQ, length=length, phase=p, amp=amp, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase), Barrier(controlQ, targetQ), X90(targetQ), Id(controlQ), Barrier(controlQ, targetQ), MEAS(controlQ), MEAS(targetQ) ] # Seq2 for p in phases: expected_seq += [ qwait(channels=(controlQ, targetQ)), X(controlQ), echoCR(controlQ, targetQ, length=length, phase=p, amp=amp, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase), Barrier(controlQ, targetQ), X90(targetQ), X(controlQ), Barrier(controlQ, targetQ), MEAS(controlQ), MEAS(targetQ) ] # Add calibration cal_seqs = get_cal_seqs_2qubits(controlQ, targetQ, calRepeats) expected_seq += cal_seqs expected_seq = testable_sequence(expected_seq) resFunction = compile_function("src/python/qgl2/basic_sequences/CR.py", "EchoCRPhase", (cR, tR, phases, riseFall, amp, length, calRepeats, canc_amp, canc_phase)) seqs = resFunction() seqs = testable_sequence(seqs) self.maxDiff = None assertPulseSequenceEqual(self, seqs, expected_seq)