Пример #1
0
    def test_sampled_segments(self):
        def my_gen(gen):
            alternating_on_off = itertools.cycle((np.ones(192), np.zeros(192)))
            chan_gen = gen
            while True:
                for _ in range(2):
                    yield next(chan_gen)
                yield next(alternating_on_off)[::2]
                yield np.zeros(192)[::2]

        with self.assertRaisesRegex(ValueError, "non integer length"):
            root_loop = LoopTests.get_test_loop(
                WaveformGenerator(waveform_data_generator=my_gen(
                    self.waveform_data_generator),
                                  duration_generator=itertools.repeat(1 / 200),
                                  num_channels=4))

            TaborProgram(root_loop, self.instr_props, ('A', 'B'), (None, None),
                         **self.program_entry_kwargs)

        root_loop = LoopTests.get_test_loop(
            WaveformGenerator(waveform_data_generator=my_gen(
                self.waveform_data_generator),
                              duration_generator=itertools.repeat(1),
                              num_channels=4))

        prog = TaborProgram(root_loop, self.instr_props, ('A', 'B'),
                            (None, None), **self.program_entry_kwargs)

        sampled, sampled_length = prog.get_sampled_segments()

        self.assertEqual(len(sampled), 3)

        prog = TaborProgram(root_loop, self.instr_props, ('A', 'B'),
                            ('C', None), **self.program_entry_kwargs)
        sampled, sampled_length = prog.get_sampled_segments()
        self.assertEqual(len(sampled), 6)

        iteroe = my_gen(self.waveform_data_generator)
        for i, sampled_seg in enumerate(sampled):
            data = [next(iteroe) for _ in range(4)]
            data = (voltage_to_uint16(data[0], 1., 0., 14),
                    voltage_to_uint16(data[1], 1., 0., 14), data[2], data[3])
            if i % 2 == 0:
                np.testing.assert_equal(sampled_seg.marker_a,
                                        np.ones(192, dtype=np.uint16)[::2])
            else:
                np.testing.assert_equal(sampled_seg.marker_a,
                                        np.zeros(192, dtype=np.uint16)[::2])
            np.testing.assert_equal(sampled_seg.marker_b,
                                    np.zeros(192, dtype=np.uint16)[::2])

            np.testing.assert_equal(sampled_seg.ch_a, data[0])
            np.testing.assert_equal(sampled_seg.ch_b, data[1])
Пример #2
0
    def upload(self, name: str,
               program: Loop,
               channels: Tuple[Optional[ChannelID], Optional[ChannelID]],
               markers: Tuple[Optional[ChannelID], Optional[ChannelID]],
               voltage_transformation: Tuple[Callable, Callable],
               force: bool = False) -> None:
        """Upload a program to the AWG.

        The policy is to prefer amending the unknown waveforms to overwriting old ones."""

        if len(channels) != self.num_channels:
            raise ValueError('Channel ID not specified')
        if len(markers) != self.num_markers:
            raise ValueError('Markers not specified')
        if len(voltage_transformation) != self.num_channels:
            raise ValueError('Wrong number of voltage transformations')

        # adjust program to fit criteria
        sample_rate = self.device.sample_rate(self._channels[0])
        make_compatible(program,
                        minimal_waveform_length=192,
                        waveform_quantum=16,
                        sample_rate=fractions.Fraction(sample_rate, 10**9))

        if name in self._known_programs:
            if force:
                self.free_program(name)
            else:
                raise ValueError('{} is already known on {}'.format(name, self.identifier))

        # They call the peak to peak range amplitude
        ranges = (self.device.amplitude(self._channels[0]),
                  self.device.amplitude(self._channels[1]))

        voltage_amplitudes = (ranges[0]/2, ranges[1]/2)

        if self._amplitude_offset_handling == AWGAmplitudeOffsetHandling.IGNORE_OFFSET:
            voltage_offsets = (0, 0)
        elif self._amplitude_offset_handling == AWGAmplitudeOffsetHandling.CONSIDER_OFFSET:
            voltage_offsets = (self.device.offset(self._channels[0]),
                               self.device.offset(self._channels[1]))
        else:
            raise ValueError('{} is invalid as AWGAmplitudeOffsetHandling'.format(self._amplitude_offset_handling))

        # parse to tabor program
        tabor_program = TaborProgram(program,
                                     channels=tuple(channels),
                                     markers=markers,
                                     device_properties=self.device.dev_properties,
                                     sample_rate=sample_rate / 10**9,
                                     amplitudes=voltage_amplitudes,
                                     offsets=voltage_offsets,
                                     voltage_transformations=voltage_transformation)

        segments, segment_lengths = tabor_program.get_sampled_segments()

        waveform_to_segment, to_amend, to_insert = self._find_place_for_segments_in_memory(segments,
                                                                                           segment_lengths)

        self._segment_references[waveform_to_segment[waveform_to_segment >= 0]] += 1

        for wf_index in np.flatnonzero(to_insert > 0):
            segment_index = to_insert[wf_index]
            self._upload_segment(to_insert[wf_index], segments[wf_index])
            waveform_to_segment[wf_index] = segment_index

        if np.any(to_amend):
            segments_to_amend = [segments[idx] for idx in np.flatnonzero(to_amend)]
            waveform_to_segment[to_amend] = self._amend_segments(segments_to_amend)

        self._known_programs[name] = TaborProgramMemory(waveform_to_segment=waveform_to_segment,
                                                        program=tabor_program)