Beispiel #1
0
def test_repeatAndVarySequence_fail_inputlength2(protosequence1):
    poss = (1, 2)
    channels = [1, 1]
    names = ['ramp', 'ramp']
    args = ['start', 'stop']
    iters = [(1, 0.2, 0.3), (1, 0.2)]

    with pytest.raises(ValueError):
        bb.repeatAndVarySequence(protosequence1, poss,
                                 channels, names, args, iters)
Beispiel #2
0
def test_repeatAndVarySequence_fail_consistency(protosequence1,
                                                squarepulse_baseelem):

    protosequence1.addElement(5, squarepulse_baseelem)

    print(protosequence1.checkConsistency())

    poss = (1,)
    channels = [1]
    names = ['ramp']
    args = ['start']
    iters = [(1, 0.2, 0.3)]

    with pytest.raises(SequenceConsistencyError):
        bb.repeatAndVarySequence(protosequence1, poss,
                                 channels, names, args, iters)
Beispiel #3
0
def test_repeatAndVarySequence_same_elements(protosequence1, pos):
    poss = (1,)
    channels = [1]
    names = ['ramp']
    args = ['start']
    iters = [(1, 0.2, 0.3)]

    newseq = bb.repeatAndVarySequence(protosequence1, poss, channels,
                                      names, args, iters)
    assert newseq.element(pos) == protosequence1.element(2)
Beispiel #4
0
def test_repeatAndVarySequence_awgspecs(protosequence1):
    poss = (1,)
    channels = [1]
    names = ['ramp']
    args = ['stop']
    iters = [[1, 0.9, 0.8]]

    newseq = bb.repeatAndVarySequence(protosequence1, poss, channels, names,
                                      args, iters)

    assert newseq._awgspecs == protosequence1._awgspecs
Beispiel #5
0
def test_repeatAndVarySequence_length(protosequence1):
    poss = [1]
    channels = [1]
    names = ['ramp']
    args = ['start']
    iters = [[1, 1.1, 1.2]]

    newseq = bb.repeatAndVarySequence(protosequence1, poss, channels, names,
                                      args, iters)

    expected_l = len(iters[0])*protosequence1.length_sequenceelements

    assert newseq.length_sequenceelements == expected_l
    def add_dc_correction(self):
        offset_time = 0.33 * self.seq_total_time
        offset_mag = -self.area / offset_time

        print(offset_mag)

        variables = ['start', 'stop', 'duration']

        poss = []
        channels_iters = []
        names = []
        args = []

        # for DC offset pulse
        for index_ch, ch in enumerate(self.channels):
            poss.extend([1 for _ in variables])
            channels_iters.extend([ch for _ in variables])
            names.extend(['offset' + '{}ch'.format(ch) for _ in variables])
            args.extend([v for v in variables])

        iters = []
        for index_ch, ch in enumerate(self.channels):

            offset = offset_mag[index_ch]
            start_ch = [offset]
            stop_ch = [offset]
            duration_ch = [offset_time]

            iters.append(start_ch)
            iters.append(stop_ch)
            iters.append(duration_ch)

        newseq = bb.repeatAndVarySequence(self.base_seq, poss, channels_iters, names, args, iters)
        # plotter(newseq)
        # plt.show()
        return newseq
    def vary_base_sequence(self, vary_name, detuning_vector, detunings, durations, lever_arms, fast_param='detuning'):
        '''fast_param = detuning or time'''
        variables = ['start', 'stop', 'duration']

        if len(lever_arms)!= len(self.channels):
            print('Lever arms must be the same length as channels')

        poss = []
        channels_iters = []
        names = []
        args = []
        if vary_name not in self.vary_name:
            print('No blueprint with that name')

        # for varied pulse
        for index_ch, ch in enumerate(self.channels):
            poss.extend([1 for _ in variables])
            channels_iters.extend([ch for _ in variables])
            names.extend([vary_name + '{}ch'.format(ch) for _ in variables])
            args.extend([v for v in variables])

        # for DC offset pulse
        for index_ch, ch in enumerate(self.channels):
            poss.extend([1 for _ in variables])
            channels_iters.extend([ch for _ in variables])
            names.extend(['offset' + '{}ch'.format(ch) for _ in variables])
            args.extend([v for v in variables])

        print(names)

        scaled_detunings = (np.array(
            [self.sequencer._scale_from_vec(detuning_vector, i).tolist() for i in detunings])*np.array(lever_arms)).T.tolist()

        offset_time = 0.33 * self.seq_total_time
        offset_mag = -self.area / offset_time

        if fast_param == 'detuning':
            iters = []

            # for exchange pulse
            for index_ch, ch in enumerate(self.channels):
                start_ch = []
                stop_ch = []
                duration_ch = []
                for t in durations:
                    start_ch.extend(scaled_detunings[index_ch])
                    stop_ch.extend(scaled_detunings[index_ch])
                    duration_ch.extend([t] * len(scaled_detunings[index_ch]))
                iters.append(start_ch)
                iters.append(stop_ch)
                iters.append(duration_ch)

            # for dc offset
            for index_ch, ch in enumerate(self.channels):
                start_ch = []
                stop_ch = []
                duration_ch = []
                for t in durations:
                    offset = (offset_mag[index_ch] + (np.array(scaled_detunings[index_ch]) * t / offset_time)).tolist()
                    start_ch.extend(offset)
                    stop_ch.extend(offset)
                    duration_ch.extend([offset_time] * len(scaled_detunings[index_ch]))
                iters.append(start_ch)
                iters.append(stop_ch)
                iters.append(duration_ch)

        elif fast_param == 'time':
            iters = []
            # for exchange pulse
            for index_ch, ch in enumerate(self.channels):
                start_ch = []
                stop_ch = []
                duration_ch = []
                for d in scaled_detunings[index_ch]:
                    start_ch.extend([d] * len(durations))
                    stop_ch.extend([d] * len(durations))
                    duration_ch.extend(durations.tolist())
                iters.append(start_ch)
                iters.append(stop_ch)
                iters.append(duration_ch)

            # for dc offset
            for index_ch, ch in enumerate(self.channels):
                start_ch = []
                stop_ch = []
                duration_ch = []
                for d in scaled_detunings[index_ch]:
                    offset = offset_mag[index_ch] + (d * durations / offset_time)
                    start_ch.extend(offset)
                    stop_ch.extend(offset)
                    duration_ch.extend([offset_time] * len(durations))
                iters.append(start_ch)
                iters.append(stop_ch)
                iters.append(duration_ch)

        newseq = bb.repeatAndVarySequence(self.base_seq, poss, channels_iters, names, args, iters)
        # plotter(newseq)
        # plt.show()
        return newseq
Beispiel #8
0
def _DPE_makeFullSequence(hightimes, trig_delay, meastime, prewaittime,
                          cycletime, no_of_avgs, no_of_pulses, pulsehigh, SR,
                          segname):
    """
    Generate the full sequence (to be uploaded exactly once).

    The sequence is a varied sequence with a baseelement consisting
    of four parts:
    1: A wait with zeros allowing the ZI to get ready. This part is
    short, but repeated waitbits times
    2: A short zero part with the marker2 trigger for the ramp
    3: The high pulse and a marker1 trigger for the ZI
    4: A short zero part with an event jump leading back to part one.
    This leading back happens no_of_avgs times.

    Args:
        hightime (float): The width of the pulse (s)p
        trig_delay (float): The delay to start measuring after the end of the
            pulse (s).
        meastime (float): The time of each measurement (s).
        prewaittime (float): The time to wait before each ramp (s).
        cycletime (float): The time of each ramp (s).
        no_of_pulses (int): The number of pulse per ramp.
        pulsehigh (float): The amplitude of the pulse (V)
        SR (int): The AWG sample rate (Sa/s)
        segname (str): The name of the high pulse segment as used internally
            by broadbean.
    """

    waitbits = 100  # no. of repetitions of the first part
    waitbittime = prewaittime / waitbits
    trig_duration = 5e-6

    if waitbittime < 10 / SR:
        raise ValueError('prewaittime too short.')

    # The pulsed part
    bp_pulse = bb.BluePrint()
    bp_pulse.setSR(SR)
    bp_pulse.insertSegment(0,
                           ramp, (pulsehigh, pulsehigh),
                           durs=hightimes[0],
                           name=segname)
    bp_pulse.insertSegment(1, ramp, (0, 0), durs=meastime, name='measure')
    # dead time for the scope to re-arm its trigger
    bp_pulse.insertSegment(2, 'waituntil', cycletime)
    bp_pulse.setSegmentMarker('measure', (trig_delay, 10e-6), 1)

    # initial wait time to allow ZI trigger to get ready. This BP is repeated
    bp_wait = bb.BluePrint()
    bp_wait.setSR(SR)
    bp_wait.insertSegment(0, 'waituntil', waitbittime)

    bp_minimalwait = bb.BluePrint()
    bp_minimalwait.setSR(SR)
    bp_minimalwait.insertSegment(0, 'waituntil', 10 / SR)  # FIXME!

    bp_ramptrig = bb.BluePrint()  # segment to trigger the ramp
    bp_ramptrig.insertSegment(0, 'waituntil', trig_duration)
    bp_ramptrig.marker2 = [(0, trig_duration)
                           ]  # the signal to trigger a new ramp
    bp_ramptrig.setSR(SR)

    bp_return = bb.BluePrint()
    bp_return.insertSegment(0, 'waituntil', 10 / SR)
    bp_return.setSR(SR)

    # The one-element router sequence
    routerelem = bb.Element()
    routerelem.addBluePrint(1, bp_minimalwait)

    routerseq = bb.Sequence()
    routerseq.addElement(1, routerelem)
    routerseq.setSequenceSettings(1, 1, 1, 0, 0)  # overridden below
    routerseq.setSR(SR)
    routerseq.setChannelVoltageRange(1, 2 * pulsehigh, 0)

    # The base sequence to be repeated and varied
    resetelem = bb.Element()
    resetelem.addBluePrint(1, bp_wait)

    trigrampelem = bb.Element()
    trigrampelem.addBluePrint(1, bp_ramptrig)

    mainelem = bb.Element()
    mainelem.addBluePrint(1, bp_pulse)

    returnelem = bb.Element()
    returnelem.addBluePrint(1, bp_return)

    baseseq = bb.Sequence()

    baseseq.addElement(1, resetelem)
    baseseq.setSequenceSettings(1, 0, waitbits, 0, 0)

    baseseq.addElement(2, trigrampelem)
    baseseq.setSequenceSettings(2, 0, 1, 0, 0)

    baseseq.addElement(3, mainelem)
    baseseq.setSequenceSettings(3, 0, no_of_pulses, 0, 0)

    baseseq.addElement(4, returnelem)
    # is an event jump even needed? Can't we just rerun from top?
    baseseq.setSequenceSettings(4, 0, 0, 1, 0)

    baseseq.setSR(SR)
    baseseq.setChannelVoltageRange(1, 2 * pulsehigh, 0)

    # Now make the variation
    poss = [3]
    channels = [1]
    names = [segname]
    args = ['duration']
    iters = [hightimes]

    # might as well have a bit of auto-debug...
    baseseq.checkConsistency(verbose=True)

    longseq = bb.repeatAndVarySequence(baseseq, poss, channels, names, args,
                                       iters)

    fullseq = routerseq + longseq

    # Now set all event jumps to point back to the first (routing) element
    for ii in range(len(hightimes)):
        fullseq.setSequenceSettings(1 + (ii + 1) * 4, 0, 0, 1, 0)
    # And set the routing element to route correctly for the first iteration
    fullseq.setSequenceSettings(1, 1, 1, 0, 2)

    return fullseq