예제 #1
0
    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)
예제 #2
0
 def addt180t(q, pulseSpacingDiff, rep):
     t180t = []
     for _ in range(rep):
         t180t += [
             Id(q, pulseSpacingDiff / 2),
             Y(q),
             Id(q, pulseSpacingDiff / 2)
         ]
     return t180t
예제 #3
0
    def test_FlipFlop(self):
        qubit = QubitFactory('q1')
        qr = QRegister('q1')
        dragParamSweep = np.linspace(0, 1, 11)
        maxNumFFs = 10

        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

        expectedseq = []
        for dragParam in dragParamSweep:
            expectedseq += [qwait(channels=(qubit, )), Id(qubit), MEAS(qubit)]
            expectedseq += addFFSeqs(dragParam, maxNumFFs, qubit)
        expectedseq += [qwait(channels=(qubit, )), X(qubit), MEAS(qubit)]
        resFunction = compile_function(
            "src/python/qgl2/basic_sequences/FlipFlop.py", "FlipFlop",
            (qr, dragParamSweep, maxNumFFs))
        seqs = resFunction()
        seqs = testable_sequence(seqs)
        assertPulseSequenceEqual(self, seqs, expectedseq)
예제 #4
0
    def test_Swap(self):
        q = QubitFactory('q1')
        mq = QubitFactory('q2')
        qr = QRegister(q)
        mqr = QRegister(mq)
        delays = np.linspace(0, 5e-6, 11)
        expectedseq = []
        for d in delays:
            expectedseq += [
                qwait(channels=(q, mq)),
                X(q),
                X(mq),
                Id(mq, length=d),
                Barrier(q, mq),
                MEAS(q),
                MEAS(mq)
            ]

        # Add calibration
        cal_seqs = get_cal_seqs_2qubits(q, mq, 2)
        expectedseq += cal_seqs

        expectedseq = testable_sequence(expectedseq)

        resFunction = compile_function(
            "src/python/qgl2/basic_sequences/Rabi.py", "Swap",
            (qr, delays, mqr))
        seqs = resFunction()
        seqs = testable_sequence(seqs)

        assertPulseSequenceEqual(self, seqs, expectedseq)
예제 #5
0
    def test_SPAM(self):
        q = QubitFactory('q1')
        qr = QRegister('q1')
        angleSweep = np.linspace(0, pi / 2, 11)
        maxSpamBlocks = 10
        expectedseq = []

        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

        for angle in angleSweep:
            expectedseq += [qwait(channels=(q, )), Id(q), MEAS(q)]
            expectedseq += spam_seqs(angle, q, maxSpamBlocks)
        expectedseq += [qwait(channels=(q, )), X(q), MEAS(q)]
        resFunction = compile_function(
            "src/python/qgl2/basic_sequences/SPAM.py", "SPAM",
            (qr, angleSweep, maxSpamBlocks))
        seqs = resFunction()
        seqs = testable_sequence(seqs)
        assertPulseSequenceEqual(self, seqs, expectedseq)
예제 #6
0
def doPulsedSpec(qubit: qreg, specOn):
    init(qubit)
    if specOn:
        X(qubit)
    else:
        Id(qubit)
    MEAS(qubit)
예제 #7
0
    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)
예제 #8
0
    def test_AllXY(self):
        # QGL1 uses QubitFactory, QGL2 uses QRegister
        q1 = QubitFactory('q1')
        qr = QRegister(q1)

        # Specify the QGL1 we expect QGL2 to generate
        # Note in this case we specify only a sample of the start
        expectedseq = []
        # Expect a single sequence 4 * 2 * 21 pulses long
        # Expect it to start like this:
        expectedseq += [
            qwait(channels=(q1, )),  # aka init(q1) aka Wait(q1)
            Id(q1),
            Id(q1),
            MEAS(q1),
            qwait(channels=(q1, )),
            Id(q1),
            Id(q1),
            MEAS(q1)
        ]

        # To turn on verbose logging in compile_function
        # from pyqgl2.ast_util import NodeError
        # from pyqgl2.debugmsg import DebugMsg
        # NodeError.MUTE_ERR_LEVEL = NodeError.NODE_ERROR_NONE
        # DebugMsg.set_level(0)

        # Now compile the QGL2 to produce the function that would generate the expected sequence.
        # Supply the path to the QGL2, the main function in that file, and a list of the args to that function.
        # Can optionally supply saveOutput=True to save the qgl1.py
        # file,
        # and intermediate_output="path-to-output-file" to save
        # intermediate products
        resFunction = compile_function(
            "src/python/qgl2/basic_sequences/AllXY.py", "AllXY", (qr, ))
        # Run the QGL2. Note that the generated function takes no arguments itself
        seqs = resFunction()
        # Transform the returned sequences into the canonical form for comparing
        # to the explicit QGL1 version above.
        # EG, 'flatten' any embedded lists of sequences.
        seqs = testable_sequence(seqs)

        # Assert that the QGL1 is the same as the generated QGL2
        self.assertEqual(len(seqs), 4 * 21 * 2)
        assertPulseSequenceEqual(self, seqs[:len(expectedseq)], expectedseq)
예제 #9
0
    def test_PiRabi(self):
        controlQ = QubitFactory('q1')
        targetQ = QubitFactory('q2')
        controlQR = QRegister(controlQ)
        targetQR = QRegister(targetQ)
        edge = EdgeFactory(controlQ, targetQ)
        lengths = np.linspace(0, 4e-6, 11)
        riseFall = 40e-9
        amp = 1
        phase = 0
        calRepeats = 2

        expected_seq = []
        # Seq1
        for l in lengths:
            expected_seq += [
                qwait(channels=(controlQ, targetQ)),
                Id(controlQ),
                flat_top_gaussian(edge,
                                  riseFall,
                                  length=l,
                                  amp=amp,
                                  phase=phase),
                Barrier(controlQ, targetQ),
                MEAS(controlQ),
                MEAS(targetQ)
            ]
        # Seq2
        for l in lengths:
            expected_seq += [
                qwait(channels=(controlQ, targetQ)),
                X(controlQ),
                flat_top_gaussian(edge,
                                  riseFall,
                                  length=l,
                                  amp=amp,
                                  phase=phase),
                X(controlQ),
                Barrier(controlQ, targetQ),
                MEAS(controlQ),
                MEAS(targetQ)
            ]

        # Add calibration
        calseq = get_cal_seqs_2qubits(controlQ, targetQ, calRepeats)
        expected_seq += calseq
        expected_seq = testable_sequence(expected_seq)

        resFunction = compile_function(
            "src/python/qgl2/basic_sequences/CR.py", "PiRabi",
            (controlQR, targetQR, lengths, riseFall, amp, phase, calRepeats))
        seqs = resFunction()
        seqs = testable_sequence(seqs)

        self.maxDiff = None
        assertPulseSequenceEqual(self, seqs, expected_seq)
예제 #10
0
def FlipFlop(qubit: qreg, dragParamSweep, maxNumFFs=10, showPlot=False):
    """
    Flip-flop sequence (X90-X90m)**n to determine off-resonance or DRAG parameter optimization.

    Parameters
    ----------
    qubit : logical channel to implement sequence (LogicalChannel) 
    dragParamSweep : drag parameter values to sweep over (iterable)
    maxNumFFs : maximum number of flip-flop pairs to do
    showPlot : whether to plot (boolean)
    """

    # Original:
    # def flipflop_seqs(dragScaling):
    #     """ Helper function to create a list of sequences with a specified drag parameter. """
    #     qubit.pulse_params['dragScaling'] = dragScaling
    #     return [[X90(qubit)] + [X90(qubit), X90m(qubit)]*rep + [Y90(qubit)] for rep in range(maxNumFFs)]

    # # Insert an identity at the start of every set to mark them off
    # originalScaling = qubit.pulse_params['dragScaling']
    # seqs = list(chain.from_iterable([[[Id(qubit)]] + flipflop_seqs(dragParam) for dragParam in dragParamSweep]))
    # qubit.pulse_params['dragScaling'] = originalScaling

    # # Add a final pi for reference
    # seqs.append([X(qubit)])

    # # Add the measurment block to every sequence
    # measBlock = MEAS(qubit)
    # for seq in seqs:
    #     seq.append(measBlock)

    # fileNames = compile_to_hardware(seqs, 'FlipFlop/FlipFlop')
    # print(fileNames)

    # if showPlot:
    #     plot_pulse_files(fileNames)

    # Insert an identity at the start of every set to mark them off
    # Want a result something like:
    # [['Id'], ['X9', 'Y9'], ['X9', 'X9', 'X9m', 'Y9'], ['X9', 'X9', 'X9m', 'X9', 'X9m', 'Y9'], ['Id'], ['X9', 'Y9'], ['X9', 'X9', 'X9m', 'Y9'], ['X9', 'X9', 'X9m', 'X9', 'X9m', 'Y9'], ['Id'], ['X9', 'Y9'], ['X9', 'X9', 'X9m', 'Y9'], ['X9', 'X9', 'X9m', 'X9', 'X9m', 'Y9']]

    originalScaling = qubit.pulse_params['dragScaling']
    for dragParam in dragParamSweep:
        init(qubit)
        Id(qubit)
        MEAS(qubit)  # FIXME: Need original dragScaling?

        # FIXME: In original this was [[Id]] + flipflop - is this
        # right?
        flipflop_seqs(dragParam, maxNumFFs, qubit)
    qubit.pulse_params['dragScaling'] = originalScaling

    # Add a final pi for reference
    init(qubit)
    X(qubit)
    MEAS(qubit)
예제 #11
0
def doSingleShot(qubit: qreg):
    """
    2-segment sequence with qubit prepared in |0> and |1>, useful for single-shot fidelity measurements and kernel calibration
    """
    init(qubit)
    Id(qubit)
    MEAS(qubit)
    init(qubit)
    X(qubit)
    MEAS(qubit)
예제 #12
0
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
예제 #13
0
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)
예제 #14
0
    def test_AllXY_alt2(self):
        q1 = QubitFactory('q1')
        qr = QRegister('q1')
        expectedseq = []
        # Expect a single sequence 4 * 2 * 21 pulses long
        # Expect it to start like this:
        expectedseq += [
            qwait(channels=(q1, )),
            Id(q1),
            Id(q1),
            MEAS(q1),
            qwait(channels=(q1, )),
            Id(q1),
            Id(q1),
            MEAS(q1)
        ]

        resFunction = compile_function("test/code/AllXY_alt.py", "doAllXY2",
                                       (qr, ))
        seqs = resFunction()
        seqs = testable_sequence(seqs)

        self.assertEqual(len(seqs), 4 * 21 * 2)
        assertPulseSequenceEqual(self, seqs[:len(expectedseq)], expectedseq)
예제 #15
0
파일: SPAM.py 프로젝트: DebasishMaji/pyqgl2
def SPAM(qubit: qreg, angleSweep, maxSpamBlocks=10, showPlot=False):
    """
    X-Y sequence (X-Y-X-Y)**n to determine quadrature angles or mixer correction.

    Parameters
    ----------
    qubit : logical channel to implement sequence (LogicalChannel) 
    angleSweep : angle shift to sweep over
    maxSpamBlocks : maximum number of XYXY block to do
    showPlot : whether to plot (boolean)
    """
    # Original:
    # 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)]

    # # Insert an identity at the start of every set to mark them off
    # seqs = list(chain.from_iterable([[[Id(qubit)]] + spam_seqs(angle) for angle in angleSweep]))

    # # Add a final pi for reference
    # seqs.append([X(qubit)])

    # # Add the measurment block to every sequence
    # measBlock = MEAS(qubit)
    # for seq in seqs:
    #     seq.append(measBlock)

    # fileNames = compile_to_hardware(seqs, 'SPAM/SPAM')
    # print(fileNames)

    # if showPlot:
    #     plot_pulse_files(fileNames)

    # Insert an identity at the start of every set to mark them off
    for angle in angleSweep:
        init(qubit)
        Id(qubit)
        MEAS(qubit)
        spam_seqs(angle, qubit, maxSpamBlocks)

    # Add a final pi for reference
    init(qubit)
    X(qubit)
    MEAS(qubit)
예제 #16
0
    def test_SingleShot(self):
        q1 = QubitFactory('q1')
        qr = QRegister(q1)
        resFunction = compile_function(
            "src/python/qgl2/basic_sequences/Rabi.py", "SingleShot", (qr, ))
        seqs = resFunction()
        seqs = testable_sequence(seqs)

        expectedseq = [
            qwait(channels=(q1, )),
            Id(q1),
            MEAS(q1),
            qwait(channels=(q1, )),
            X(q1),
            MEAS(q1)
        ]

        assertPulseSequenceEqual(self, seqs, expectedseq)
예제 #17
0
 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
예제 #18
0
 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
예제 #19
0
    def test_InversionRecovery(self):
        q = QubitFactory('q1')
        qr = QRegister('q1')
        delays = np.linspace(0, 5e-6, 11)
        calRepeats = 2
        expectedseq = []
        for d in delays:
            expectedseq += [qwait(channels=(q, )), X(q), Id(q, d), 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", "InversionRecovery",
            (qr, delays, calRepeats))
        seqs = resFunction()
        seqs = testable_sequence(seqs)
        assertPulseSequenceEqual(self, seqs, expectedseq)
예제 #20
0
def doSwap(qubit: qreg, mqubit: qreg, delays):
    # Original:
    # 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
    for d in delays:
        with concur:
            init(qubit)
            init(mqubit)
        X(qubit)
        X(mqubit)
        Id(mqubit, d)
        with concur:
            MEAS(mqubit)
            MEAS(qubit)

    create_cal_seqs((mqubit, qubit), 2)
예제 #21
0
def InversionRecoveryq1(qubit: qreg, delays, showPlot=False, calRepeats=2, suffix=False):
    """
    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)
    """

    # Original: 
    # # 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'+('_'+qubit.label)*suffix+'/T1'+('_'+qubit.label)*suffix)
    # print(fileNames)

    # if showPlot:
    #     plot_pulse_files(fileNames)
    seqs = []
    for d in delays:
        seq = []
        seq.append(X(qubit))
        seq.append(Id(qubit, d))
        seq.append(MEAS(qubit))
        seqs.append(seq)

    # Tack on calibration
#    seqs = addCalibration(seqs, (qubit,), calRepeats)

    # Calculate label
    label = 'T1'+('_'+qubit.label)*suffix
    fullLabel = label + '/' + label
예제 #22
0
def FlipFlopMin():
    # FIXME: No args
    qubit = QubitFactory('q1')
    dragParamSweep = np.linspace(0, 5e-6, 11)  # FIXME
    maxNumFFs = 10

    # FIXME: cause qubit is a placeholder, can't access pulse_params
    # originalScaling = qubit.pulse_params['dragScaling']
    for dragParam in dragParamSweep:
        init(qubit)
        Id(qubit)
        MEAS(qubit)  # FIXME: Need original dragScaling?

        # FIXME: In original this was [[Id]] + flipflop - is this
        # right?
        flipflop_seqs(dragParam, maxNumFFs, qubit)
    # FIXME: cause qubit is a placeholder, can't access pulse_params
    # qubit.pulse_params['dragScaling'] = originalScaling

    # Add a final pi for reference
    init(qubit)
    X(qubit)
    MEAS(qubit)
예제 #23
0
def SingleQubitRBT(qubit: qreg,
                   seqFileDir,
                   analyzedPulse: pulse,
                   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)
    """

    # Original:
    # # Setup a pulse library
    # pulseLib = [AC(qubit, cliffNum) for cliffNum in range(24)]
    # pulseLib.append(analyzedPulse)
    # measBlock = MEAS(qubit)

    # seqs = []
    # for ct in range(10):
    #     fileName = 'RBT_Seqs_fast_{0}_F1.txt'.format(ct+1)
    #     tmpSeqs = []
    #     with open(os.path.join(seqFileDir, fileName),'r') as FID:
    #         fileReader = reader(FID)
    #         for pulseSeqStr in fileReader:
    #             seq = []
    #             for pulseStr in pulseSeqStr:
    #                 seq.append(pulseLib[int(pulseStr)-1])
    #             seq.append(measBlock)
    #             tmpSeqs.append(seq)
    #         seqs += tmpSeqs[:12]*12 + tmpSeqs[12:-12] + tmpSeqs[-12:]*12

    # seqsPerFile = 100
    # numFiles = len(seqs)//seqsPerFile

    # for ct in range(numFiles):
    #     chunk = seqs[ct*seqsPerFile:(ct+1)*seqsPerFile]
    #     # Tack on the calibration scalings
    #     numCals = 4
    #     chunk += [[Id(qubit), measBlock]]*numCals + [[X(qubit), measBlock]]*numCals
    #     fileNames = compile_to_hardware(chunk, 'RBT/RBT', suffix='_{0}'.format(ct+1))

    # if showPlot:
    #     plot_pulse_files(fileNames)

    pulseSeqStrs = []
    for ct in range(10):
        fileName = 'RBT_Seqs_fast_{0}_F1.txt'.format(ct + 1)
        tmpSeqs = []
        with open(os.path.join(seqFileDir, fileName), 'r') as FID:
            fileReader = reader(FID)
            for pulseSeqStr in fileReader:
                tmpSeqs.append(pulseSeqStr)
            pulseSeqStrs = tmpSeqs[:12] * 12 + tmpSeqs[
                12:-12] + tmpSeqs[-12:] * 12

    numSeqs = len(pulseSeqStrs)
    seqsPerFile = 100
    numFiles = numSeqs // seqsPerFile
    numCals = 4

    for ct in range(numFiles):
        for s in range(seqsPerFile):
            init(qubit)
            seqStr = pulseSeqStrs[ct * seqsPerFile + s]
            getPulseSeq(qubit, seqStr)
        # Add numCals calibration scalings
        for _ in range(numCals):
            init(qubit)
            Id(qubit)
            MEAS(qubit)

            init(qubit)
            X(qubit)
            MEAS(qubit)
        # FIXME: Then magically get the sequences here....
        # This needs to get refactored....
        # We need to split creating seqs from c_to_h
        fileNames = compile_to_hardware([],
                                        'RBT/RBT',
                                        suffix='_{0}'.format(ct + 1),
                                        qgl2=True)

    # FIXME: Do this from calling function
    if showPlot:
        plot_pulse_files(fileNames)
예제 #24
0
def SingleQubitIRB_AC(qubit: qreg, seqFile, showPlot=False):
    """
    Single qubit interleaved randomized benchmarking using atomic Clifford pulses. 

    Parameters
    ----------
    qubit : logical channel to implement sequence (LogicalChannel)
    seqFile : file containing sequence strings
    showPlot : whether to plot (boolean)
    """

    # Original:
    # # Setup a pulse library
    # pulseLib = [AC(qubit, cliffNum) for cliffNum in range(24)]
    # pulseLib.append(pulseLib[0])
    # measBlock = MEAS(qubit)

    # with open(seqFile,'r') as FID:
    #     fileReader = reader(FID)
    #     seqs = []
    #     for pulseSeqStr in fileReader:
    #         seq = []
    #         for pulseStr in pulseSeqStr:
    #             seq.append(pulseLib[int(pulseStr)])
    #         seq.append(measBlock)
    #         seqs.append(seq)

    # # Hack for limited APS waveform memory and break it up into multiple files
    # # We've shuffled the sequences so that we loop through each gate length on the inner loop
    # numRandomizations = 36
    # for ct in range(numRandomizations):
    #     chunk = seqs[ct::numRandomizations]
    #     chunk1 = chunk[::2]
    #     chunk2 = chunk[1::2]
    #     # Tack on the calibration scalings
    #     chunk1 += [[Id(qubit), measBlock], [X(qubit), measBlock]]
    #     fileNames = compile_to_hardware(chunk1, 'RB/RB', suffix='_{0}'.format(2*ct+1))
    #     chunk2 += [[Id(qubit), measBlock], [X(qubit), measBlock]]
    #     fileNames = compile_to_hardware(chunk2, 'RB/RB', suffix='_{0}'.format(2*ct+2))

    # if showPlot:
    #     plot_pulse_files(fileNames)

    pulseSeqStrs = []
    with open(seqFile, 'r') as FID:
        fileReader = reader(FID)
        # each line in the file is a sequence, but I don't know how many that is
        for pulseSeqStr in fileReader:
            pulseSeqStrs.append(pulseSeqStr)
    numSeqs = len(pulseSeqStrs)

    # Hack for limited APS waveform memory and break it up into multiple files
    # We've shuffled the sequences so that we loop through each gate length on the inner loop
    numRandomizations = 36
    fileNames = []
    for ct in range(numRandomizations):
        doCt = ct
        isOne = True
        while doCt < numSeqs:
            getPulseSeq(qubit, pulseSeqStrs[doCt])

            # Tack on calibration scalings
            if isOne:
                init(qubit)
                Id(qubit)
                MEAS(qubit)
                init(qubit)
                X(qubit)
                meas(qubit)
            else:
                init(qubit)
                Id(qubit)
                meas(qubit)
                init(qubit)
                X(qubit)
                meas(qubit)

            # Now write these sequences
            # FIXME: Then magically get the sequences here....
            # This needs to get refactored....
            # We need to split creating seqs from c_to_h
            fileNames = compile_to_hardware(
                [],
                'RB/RB',
                suffix='_{0}'.format(2 * ct + 1 + 1 * (not isOne)),
                qgl2=True)

            doCt += numRandomizations
            isOne = not isOne

    if showPlot:
        plot_pulse_Files(fileNames)
예제 #25
0
def idPulseCentered(qubit, pulseSpacing):
    return Id(qubit, length=(pulseSpacing - qubit.pulse_params["length"]) / 2)
예제 #26
0
    def test_EchoCRLen(self):
        controlQ = QubitFactory('q1')
        targetQ = QubitFactory('q2')
        cR = QRegister('q1')  # Equivalent to QRegister(controlQ)
        tR = QRegister('q2')
        # FIXME: Better values!?
        lengths = np.linspace(0, 2e-6, 11)
        riseFall = 40e-9
        amp = 1
        phase = 0
        calRepeats = 2
        canc_amp = 0
        canc_phase = np.pi / 2

        expected_seq = []
        # Seq1
        for l in lengths:
            expected_seq += [
                qwait(channels=(controlQ, targetQ)),
                Id(controlQ),
                echoCR(controlQ,
                       targetQ,
                       length=l,
                       phase=phase,
                       amp=amp,
                       riseFall=riseFall,
                       canc_amp=canc_amp,
                       canc_phase=canc_phase),
                Id(controlQ),
                Barrier(controlQ, targetQ),
                MEAS(controlQ),
                MEAS(targetQ)
            ]
        # Seq2
        for l in lengths:
            expected_seq += [
                qwait(channels=(controlQ, targetQ)),
                X(controlQ),
                echoCR(controlQ,
                       targetQ,
                       length=l,
                       phase=phase,
                       amp=amp,
                       riseFall=riseFall,
                       canc_amp=canc_amp,
                       canc_phase=canc_phase),
                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",
                                       "EchoCRLen",
                                       (cR, tR, lengths, riseFall, amp, phase,
                                        calRepeats, canc_amp, canc_phase))
        seqs = resFunction()
        seqs = testable_sequence(seqs)

        self.maxDiff = None
        assertPulseSequenceEqual(self, seqs, expected_seq)
예제 #27
0
    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)