def test_waveform_gate(self): runtime = init_runtime() sequence = init_gate_sequence(runtime) slice0 = FixedSlice("slice_0", 0, 5e-9) sequence.add_slice(slice0) waveform0 = DC(5e-9, 2) waveform1 = Blank(1e-9).concat(DC(3e-9, 1)).concat(Blank(1e-9)) slice0.add_waveform(mock_awg10, waveform0) slice0.add_waveform(mock_awg10_gate, waveform1) sequence.setup_trigger() sequence.setup_channels() sequence.run_channels() expected_waveform, expected_amp = (waveform1 * waveform0) \ .normalized_sample(mock_awg0.device.sample_rate) assert isinstance(expected_waveform, np.ndarray) assert isinstance(mock_awg0.device.raw_waveform, np.ndarray) assert len(expected_waveform) == len(mock_awg10.device.raw_waveform) assert expected_amp == mock_awg10.device.raw_waveform_amp assert (mock_awg10.device.raw_waveform == expected_waveform).all()
def test_slice_padding_across_multiple_trigger_channels(self): runtime = init_runtime() sequence, slice0, slice1, slice2 = init_fixed_sequence(runtime) assert isinstance(slice2, FixedLengthSlice) waveform_awg0 = DC(0.1e-6, 1) waveform_awg2 = DC(0.1e-6, 1) waveform_awg4 = DC(0.1e-6, 1) slice2.add_waveform(mock_awg0, waveform_awg0) slice2.add_waveform(mock_awg3, waveform_awg2) slice2.add_waveform(mock_awg6, waveform_awg4) sequence.setup_trigger() sequence.setup_channels() sequence.run_channels() awg_0_expected_waveform, _ = Blank(2e-6 + 0.9e-6).concat(waveform_awg0) \ .normalized_sample(mock_awg0.device.sample_rate) awg_2_expected_waveform, _ = Blank(1e-6 + 0.9e-6).concat(waveform_awg2) \ .normalized_sample(mock_awg3.device.sample_rate) awg_4_expected_waveform, _ = Blank(0.9e-6).concat(waveform_awg4) \ .normalized_sample(mock_awg6.device.sample_rate) for exp, awg in [ (awg_0_expected_waveform, mock_awg0.device.raw_waveform), (awg_2_expected_waveform, mock_awg3.device.raw_waveform), (awg_4_expected_waveform, mock_awg6.device.raw_waveform) ]: assert isinstance(exp, np.ndarray) assert isinstance(awg, np.ndarray) assert len(exp) == len(awg) assert (exp == awg).all()
def flatten_waveform(self): channel_updated = self.get_updated_channel() if not channel_updated: # If no waveform change detected, return processed_self_waveforms = {} # Second scan, updated waveforms stored in this slice for channel in channel_updated: if channel in self.waveforms: processed_self_waveforms[channel] = self.waveforms[channel] processed_sub_waveforms = {} # Third scan, updated waveforms stored in sub slices for channel in channel_updated: pointer = 0 for sub_slice in self.sub_slices: assert channel not in processed_self_waveforms, \ f"Waveform for channel {channel} defined in both parent "\ "slice and sub slice, causing conflicts." if channel not in sub_slice.get_channels(): pointer += sub_slice.duration continue if pointer == 0: processed_sub_waveforms[channel] = \ sub_slice.get_waveform(channel) pointer += sub_slice.duration continue if channel not in processed_sub_waveforms: processed_sub_waveforms[channel] = Blank(pointer) padding_len = pointer - processed_sub_waveforms[channel].width if padding_len > 1e-15: processed_sub_waveforms[channel] = \ processed_sub_waveforms[channel].concat(Blank(padding_len)) processed_sub_waveforms[channel] = \ processed_sub_waveforms[channel].concat( sub_slice.get_waveform(channel) ) pointer += sub_slice.duration if channel in processed_sub_waveforms: padding_len = pointer - processed_sub_waveforms[channel].width if padding_len > 1e-15: processed_sub_waveforms[channel] = \ processed_sub_waveforms[channel].concat(Blank(padding_len)) self.processed_waveforms = processed_self_waveforms self.processed_waveforms.update(processed_sub_waveforms) self._compiled = True
def test_sequence_stack(self): runtime = init_runtime() sequence, slice0, slice1, slice2 = init_fixed_sequence(runtime) assert isinstance(slice0, FixedLengthSlice) waveform1 = DC(0.1e-6, 1) waveform2 = DC(0.1e-6, 2) waveform3 = DC(0.1e-6, 3) slice0.add_waveform(mock_awg0, waveform1) slice0.add_waveform(mock_awg0, waveform2) slice0.add_waveform(mock_awg0, waveform3) sequence.setup_trigger() sequence.setup_channels() sequence.run_channels() expected_waveform, _ = Blank(2.7e-6).concat(waveform1).concat(waveform2) \ .concat(waveform3) \ .normalized_sample(mock_awg0.device.sample_rate) assert isinstance(expected_waveform, np.ndarray) assert isinstance(mock_awg0.device.raw_waveform, np.ndarray) assert len(expected_waveform) == len(mock_awg0.device.raw_waveform) assert (mock_awg0.device.raw_waveform == expected_waveform).all()
def test_same_awg_channel_across_slices(self): runtime = init_runtime() sequence, slice0, slice1, slice2 = init_fixed_sequence(runtime) waveform_slice1 = DC(0.1e-6, 2) waveform_slice2 = DC(0.1e-6, 3) slice1.add_waveform(mock_awg0, waveform_slice1) slice2.add_waveform(mock_awg0, waveform_slice2) sequence.setup_trigger() sequence.setup_channels() sequence.run_channels() expected_waveform, _ = Blank(1.9e-6).concat(waveform_slice1) \ .concat(Blank(0.9e-6)).concat(waveform_slice2) \ .normalized_sample(mock_awg0.device.sample_rate) assert isinstance(expected_waveform, np.ndarray) assert isinstance(mock_awg0.device.raw_waveform, np.ndarray) assert len(expected_waveform) == len(mock_awg0.device.raw_waveform) assert (mock_awg0.device.raw_waveform == expected_waveform).all()
def flatten_waveform(self): super().flatten_waveform() for channel in self.get_updated_channel(): if channel not in self.processed_waveforms: continue waveform_width = self.processed_waveforms[channel].width padding_width = self.duration - waveform_width assert padding_width > -1e-15, \ f"Waveform of this slice longer than the total " \ f"duration of this slice." if padding_width > 1e-15: if (channel not in self.waveform_padding_scheme or self.waveform_padding_scheme[channel] == PaddingPosition.PADDING_BEFORE): self.processed_waveforms[channel] = \ Blank(padding_width).concat(self.processed_waveforms[channel]) else: self.processed_waveforms[channel] = \ Blank(padding_width).append_to( self.processed_waveforms[channel])
def test_sub_slice_overleaf(self): runtime = init_runtime() sequence = init_nake_sequence(runtime) slice0 = FixedSlice("slice_0", 0, 20e-9) sequence.add_slice(slice0) sub_slice0 = FlexSlice("sub_slice0") sub_slice1 = FlexSlice("sub_slice1") sub_slice2 = FlexSlice("sub_slice2") slice0.add_sub_slice(sub_slice0) slice0.add_sub_slice(sub_slice1) slice0.add_sub_slice(sub_slice2) waveform0 = DC(5e-9, 1) waveform1 = DC(5e-9, 2) waveform2 = DC(10e-9, 3) sub_slice0.add_waveform(mock_awg0, waveform0) sub_slice1.add_waveform(mock_awg1, waveform1) sub_slice2.add_waveform(mock_awg2, waveform2) sequence.setup_trigger() sequence.setup_channels() sequence.run_channels() print(slice0.processed_waveforms[mock_awg0]) print(slice0.processed_waveforms[mock_awg1]) print(slice0.processed_waveforms[mock_awg2]) print(sequence.last_compiled_waveforms[mock_awg0]) print(sequence.last_compiled_waveforms[mock_awg1]) print(sequence.last_compiled_waveforms[mock_awg2]) awg_0_expected_waveform, _ = waveform0.concat(Blank(5e-9)).concat(Blank(10e-9))\ .normalized_sample(mock_awg0.device.sample_rate) awg_1_expected_waveform, _ = Blank(5e-9).concat(waveform1).concat(Blank(10e-9)) \ .normalized_sample(mock_awg1.device.sample_rate) awg_2_expected_waveform, _ = Blank(5e-9).concat(Blank(5e-9)).concat(waveform2)\ .normalized_sample(mock_awg2.device.sample_rate) for i, (exp, awg) in enumerate([ (awg_0_expected_waveform, mock_awg0.device.raw_waveform), (awg_1_expected_waveform, mock_awg1.device.raw_waveform), (awg_2_expected_waveform, mock_awg2.device.raw_waveform) ]): print(i) assert isinstance(exp, np.ndarray) assert isinstance(awg, np.ndarray) assert len(exp) == len(awg) assert (exp == awg).all()
def test_stack_procedures(self): runtime = init_runtime() sequence, slice0, slice1, slice2 = init_fixed_sequence(runtime) assert isinstance(slice0, Slice) cycle = self.MyTestStackCycle(runtime, slice0, mock_awg0, [(0.1e-6, 1), (0.1e-6, 2), (0.1e-6, 3)]) cycle.run() expected_waveform, _ = Blank(2.7e-6).concat(DC(0.1e-6, 1)) \ .concat(DC(0.1e-6, 2)).concat(DC(0.1e-6, 3)) \ .normalized_sample(mock_awg0.device.sample_rate) assert isinstance(expected_waveform, np.ndarray) assert isinstance(mock_awg0.device.raw_waveform, np.ndarray) assert len(expected_waveform) == len(mock_awg0.device.raw_waveform) assert (mock_awg0.device.raw_waveform == expected_waveform).all()
def test_slice_padding_after(self): runtime = init_runtime() sequence, slice0, slice1, slice2 = init_fixed_sequence(runtime) assert isinstance(slice0, FixedLengthSlice) waveform = DC(0.1e-6, 1) slice0.set_waveform_padding(mock_awg0, PaddingPosition.PADDING_BEHIND) slice0.add_waveform(mock_awg0, waveform) sequence.setup_trigger() sequence.setup_channels() sequence.run_channels() expected_waveform, _ = waveform.concat(Blank(3e-6 - 0.1e-6)) \ .normalized_sample(mock_awg0.device.sample_rate) assert isinstance(expected_waveform, np.ndarray) assert isinstance(mock_awg0.device.raw_waveform, np.ndarray) assert len(expected_waveform) == len(mock_awg0.device.raw_waveform) assert (mock_awg0.device.raw_waveform == expected_waveform).all()
def compile_waveforms(self): self.channel_update_list = [] compiled_waveforms = self.last_compiled_waveforms max_compiled_waveform_length = 0 for slice in self.slices: channel_updated = slice.get_updated_channel() if not channel_updated: continue if abs(self._slice_length_history[slice] - slice.duration) > 1e-15: channel_updated = self.channels.values() self._slice_length_history[slice] = slice.duration if isinstance(slice, FixedSlice): start_from = slice.start_from else: start_from = max_compiled_waveform_length for channel_name, channel in self.channels.items(): if channel not in channel_updated: continue if channel not in self.channel_update_list: self.channel_update_list.append(channel) if channel in self.last_compiled_waveforms: del self.last_compiled_waveforms[channel] trigger_start_from = self.channel_to_trigger[channel].raise_at assert trigger_start_from <= start_from, \ f"Waveform assigned to channel before it is triggered! " \ f"(Slice {slice.name}, Channel {channel_name})" waveform = slice.get_waveform(channel) if not waveform: waveform = Blank(0) max_compiled_waveform_length = max( start_from + waveform.width, max_compiled_waveform_length) if channel in compiled_waveforms: assert (compiled_waveforms[channel].width <= start_from - trigger_start_from), \ f"Waveform overlap detected on channel {channel_name}." if (compiled_waveforms[channel].width < start_from - trigger_start_from): padding_length = (start_from - trigger_start_from - compiled_waveforms[channel].width) if padding_length > 1e-15: compiled_waveforms[channel] = \ compiled_waveforms[channel].concat( Blank(padding_length)) compiled_waveforms[channel] = compiled_waveforms[ channel].concat(waveform) else: padding_length = start_from - trigger_start_from if padding_length > 1e-15: compiled_waveforms[channel] = \ Blank(padding_length).concat(waveform) else: compiled_waveforms[channel] = waveform slice.clear_channel_updated_flag() self.last_compiled_waveforms = compiled_waveforms return compiled_waveforms