Exemple #1
0
    def __init__(
        self,
        program: Loop,
        device_properties: Mapping,
        channels: Tuple[Optional[ChannelID], Optional[ChannelID]],
        markers: Tuple[Optional[ChannelID], Optional[ChannelID]],
        amplitudes: Tuple[float, float],
        offsets: Tuple[float, float],
        voltage_transformations: Tuple[Optional[callable], Optional[callable]],
        sample_rate: TimeType,
        mode: TaborSequencing = None,
        repetition_mode: str = "infinite",
    ):
        if len(channels) != device_properties['chan_per_part']:
            raise TaborException(
                'TaborProgram only supports {} channels'.format(
                    device_properties['chan_per_part']))
        if len(markers) != device_properties['chan_per_part']:
            raise TaborException(
                'TaborProgram only supports {} markers'.format(
                    device_properties['chan_per_part']))
        used_channels = frozenset(set(channels).union(markers) - {None})

        if program.repetition_count > 1 or program.depth() == 0:
            program.encapsulate()

        if mode is None:
            if program.depth() > 1:
                mode = TaborSequencing.ADVANCED
            else:
                mode = TaborSequencing.SINGLE

        super().__init__(
            loop=program,
            channels=channels,
            markers=markers,
            amplitudes=amplitudes,
            offsets=offsets,
            voltage_transformations=voltage_transformations,
            sample_rate=sample_rate,
            waveforms=[]  # no sampling happens here
        )

        self._used_channels = used_channels
        self._parsed_program = None  # type: Optional[ParsedProgram]
        self._mode = None
        self._device_properties = device_properties
        self._repetition_mode = repetition_mode

        assert mode in (TaborSequencing.ADVANCED,
                        TaborSequencing.SINGLE), "Invalid mode"
        if mode == TaborSequencing.SINGLE:
            self.setup_single_sequence_mode()
        else:
            self.setup_advanced_sequence_mode()

        self._sampled_segments = self._calc_sampled_segments()
Exemple #2
0
def parse_single_seq_program(program: Loop, used_channels: FrozenSet[ChannelID]) -> ParsedProgram:
    assert program.depth() == 1

    sequencer_table = []
    waveforms = OrderedDict()
    volatile_parameter_positions = {}

    for position, (waveform, repetition_definition, volatile_repetition) in enumerate(
            (waveform_loop.waveform.get_subset_for_channels(used_channels),
             waveform_loop.repetition_definition, waveform_loop.volatile_repetition)
            for waveform_loop in program):
        if waveform in waveforms:
            waveform_index = waveforms[waveform]
        else:
            waveform_index = len(waveforms)
            waveforms[waveform] = waveform_index

        sequencer_table.append((TableDescription(repetition_count=int(repetition_definition),
                                                 element_id=waveform_index,
                                                 jump_flag=0), volatile_repetition))
        if volatile_repetition is not None:
            volatile_parameter_positions[(0, position)] = repetition_definition

    return ParsedProgram(
        advanced_sequencer_table=[TableEntry(repetition_count=program.repetition_count, element_number=1, jump_flag=0)],
        sequencer_tables=[sequencer_table],
        waveforms=tuple(waveforms.keys()),
        volatile_parameter_positions=volatile_parameter_positions
    )
Exemple #3
0
def parse_program(program: Loop,
                  channels: Tuple[Optional[ChannelID], ...],
                  markers: Tuple[Tuple[Optional[ChannelID], Optional[ChannelID]], ...],
                  sample_rate: TimeType,
                  amplitudes: Tuple[float, ...],
                  voltage_transformations: Tuple[Callable, ...],
                  offsets: Tuple[float, ...] = None) -> Tuple[Sequence[tek_awg.SequenceEntry],
                                                              Sequence[tek_awg.Waveform]]:
    """Convert the program into a sequence of sequence table entries and a sequence of waveforms that can be uploaded
    to the device."""
    assert program.depth() == 1, ("Invalid program depth: %d" % program.depth())
    assert program.repetition_count == 1, ("Cannot repeat program a finite number of times (only once not %d)" %
                                           program.repetition_count)

    # For backward compatibility
    # EDIT: I think this is not needed? (Simon)
    if offsets is None:
        offsets = (0.,) * len(amplitudes)

    assert len(channels) == len(markers) == len(amplitudes) == len(voltage_transformations) == len(offsets)

    sequencing_elements = []

    ch_waveforms = {}
    bin_waveforms = {}

    sample_rate_in_GHz = sample_rate / 10**9

    time_array, n_samples = get_sample_times([loop.waveform for loop in program],
                                             sample_rate_in_GHz=sample_rate_in_GHz)

    channel_wise_kwargs = [dict(voltage_to_uint16_kwargs=dict(output_amplitude=amplitude,
                                                              output_offset=offset,
                                                              resolution=14),
                                voltage_transformation=voltage_trafo)
                           for amplitude, offset, voltage_trafo in zip(amplitudes, offsets, voltage_transformations)]

    # List of Tuple[positional channel tuple, set chs to sample]
    channel_infos = [((channel, marker_1, marker_2), {channel, marker_1, marker_2} - {None})
                     for channel, (marker_1, marker_2) in zip(channels, markers)]

    for n_sample, loop in zip(n_samples, program):

        entries = []

        for (positional_chs, chs_to_sample), kwargs in zip(channel_infos, channel_wise_kwargs):

            if not chs_to_sample:
                entries.append(n_sample)
                bin_waveforms[n_sample] = None

            else:
                ch_waveform = loop.waveform.get_subset_for_channels(chs_to_sample)

                if ch_waveform not in ch_waveforms:
                    bin_waveform = _make_binary_waveform(ch_waveform,
                                                         time_array[:n_sample],
                                                         *positional_chs, **kwargs)

                    if bin_waveform in bin_waveforms:
                        # use identical binary waveform already created to save memory
                        bin_waveform = ch_waveforms[bin_waveforms[bin_waveform]]
                    else:
                        bin_waveforms[bin_waveform] = ch_waveform

                    ch_waveforms[ch_waveform] = bin_waveform

                entries.append(ch_waveforms[ch_waveform])

        sequencing_elements.append(
            tek_awg.SequenceEntry(entries=entries,
                                  loop_count=loop.repetition_count)
        )
    return tuple(sequencing_elements), tuple(bin_waveforms.keys())