Esempio n. 1
0
    def _calc_sampled_segments(self) -> Tuple[Sequence[TaborSegment], Sequence[int]]:
        """
        Returns:
            (segments, segment_lengths)
        """
        time_array, segment_lengths = get_sample_times(self._parsed_program.waveforms, self._sample_rate)

        if np.any(segment_lengths % 16 > 0) or np.any(segment_lengths < 192):
            raise TaborException('At least one waveform has a length that is smaller 192 or not a multiple of 16')

        segments = []
        for i, waveform in enumerate(self._parsed_program.waveforms):
            t = time_array[:segment_lengths[i]]
            marker_time = t[::2]
            segment_a = self._channel_data(waveform, t, 0)
            segment_b = self._channel_data(waveform, t, 1)
            assert (len(segment_a) == len(t))
            assert (len(segment_b) == len(t))
            marker_a = self._marker_data(waveform, marker_time, 0)
            marker_b = self._marker_data(waveform, marker_time, 1)
            segment = TaborSegment.from_sampled(ch_a=segment_a,
                                   ch_b=segment_b,
                                   marker_a=marker_a,
                                   marker_b=marker_b)
            segments.append(segment)
        return segments, segment_lengths
Esempio n. 2
0
    def _sample_waveforms(self, waveforms: Sequence[Waveform]) -> List[Tuple[Tuple[numpy.ndarray, ...],
                                                                             Tuple[numpy.ndarray, ...]]]:
        sampled_waveforms = []

        time_array, segment_lengths = get_sample_times(waveforms, self._sample_rate)
        for waveform, segment_length in zip(waveforms, segment_lengths):
            wf_time = time_array[:segment_length]

            sampled_channels = []
            for channel, trafo, amplitude, offset in zip(self._channels, self._voltage_transformations,
                                                         self._amplitudes, self._offsets):
                if channel is None:
                    sampled_channels.append(self._sample_empty_channel(wf_time))
                else:
                    sampled = waveform.get_sampled(channel, wf_time)
                    if trafo is not None:
                        sampled = trafo(sampled)
                    sampled = sampled - offset
                    sampled /= amplitude
                    sampled_channels.append(waveform.get_sampled(channel, wf_time))

            sampled_markers = []
            for marker in self._markers:
                if marker is None:
                    sampled_markers.append(self._sample_empty_marker(wf_time))
                else:
                    sampled_markers.append(waveform.get_sampled(marker, wf_time) != 0)

            sampled_waveforms.append((tuple(sampled_channels), tuple(sampled_markers)))
        return sampled_waveforms
Esempio n. 3
0
    def test_get_sample_times_single_wf(self):
        sample_rate = TimeType(12, 10)
        wf = DummyWaveform(duration=TimeType(40, 12))

        expected_times = np.arange(4) / 1.2
        times, n_samples = get_sample_times(wf, sample_rate_in_GHz=sample_rate)

        np.testing.assert_equal(times, expected_times)
        np.testing.assert_equal(n_samples, np.asarray(4))
Esempio n. 4
0
    def __init__(self, loop: Loop,
                 channels: Tuple[Optional[ChannelID], ...],
                 markers: Tuple[Optional[ChannelID], ...],
                 amplitudes: Tuple[float, ...],
                 offsets: Tuple[float, ...],
                 voltage_transformations: Tuple[Optional[Callable], ...],
                 sample_rate: TimeType):
        assert len(channels) == len(amplitudes) == len(offsets) == len(voltage_transformations)

        self._channels = tuple(channels)
        self._markers = tuple(markers)
        self._amplitudes = tuple(amplitudes)
        self._offsets = tuple(offsets)
        self._voltage_transformations = tuple(voltage_transformations)

        self._sample_rate = sample_rate

        self._loop = loop
        self._waveforms = {node.waveform: None for node in loop.get_depth_first_iterator() if node.is_leaf()}

        time_array, segment_lengths = get_sample_times(self._waveforms.keys(), sample_rate)

        for waveform, segment_length in zip(self._waveforms.keys(), segment_lengths):
            wf_time = time_array[:segment_length]

            sampled_channels = []
            for channel, trafo, amplitude, offset in zip(channels, voltage_transformations, amplitudes, offsets):
                if channel is None:
                    sampled_channels.append(None)
                else:
                    sampled = waveform.get_sampled(channel, wf_time)
                    if trafo:
                        sampled = trafo(sampled)
                    sampled = sampled - offset
                    sampled /= amplitude
                    sampled_channels.append(waveform.get_sampled(channel, wf_time))

            sampled_markers = []
            for marker in markers:
                if marker is None:
                    sampled_markers.append(None)
                else:
                    sampled_markers.append(waveform.get_sampled(marker, wf_time) != 0)
            self._waveforms[waveform] = (tuple(sampled_channels), tuple(sampled_markers))
Esempio n. 5
0
    def test_get_sample_times(self):
        sample_rate = TimeType.from_fraction(12, 10)
        wf1 = DummyWaveform(duration=TimeType.from_fraction(20, 12))
        wf2 = DummyWaveform(duration=TimeType.from_fraction(400000000001, 120000000000))
        wf3 = DummyWaveform(duration=TimeType.from_fraction(1, 10**15))

        expected_times = np.arange(4) / 1.2
        times, n_samples = get_sample_times([wf1, wf2], sample_rate_in_GHz=sample_rate)
        np.testing.assert_equal(expected_times, times)
        np.testing.assert_equal(n_samples, np.asarray([2, 4]))

        with self.assertRaises(AssertionError):
            get_sample_times([], sample_rate_in_GHz=sample_rate)

        with self.assertRaisesRegex(ValueError, "non integer length"):
            get_sample_times([wf1, wf2], sample_rate_in_GHz=sample_rate, tolerance=0.)

        with self.assertRaisesRegex(ValueError, "length <= zero"):
            get_sample_times([wf1, wf3], sample_rate_in_GHz=sample_rate)
Esempio n. 6
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())