Beispiel #1
0
def doRabiAmpPi(qubit: qreg, mqubit: qreg, amps, phase):
    for amp in amps:
        with concur:
            init(qubit)
            init(mqubit)
        X(mqubit)
        Utheta(qubit, amp=amp, phase=phase)
        X(mqubit)
        MEAS(mqubit)
Beispiel #2
0
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)
Beispiel #3
0
 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
Beispiel #4
0
def doPulsedSpec(qubit: qreg, specOn):
    init(qubit)
    if specOn:
        X(qubit)
    else:
        Id(qubit)
    MEAS(qubit)
Beispiel #5
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)
Beispiel #6
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)
Beispiel #7
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)
Beispiel #8
0
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)
Beispiel #9
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
Beispiel #10
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)
Beispiel #11
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)
Beispiel #12
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)