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, waveforms: Sequence[Waveform] = None): """ Args: loop: channels: markers: amplitudes: offsets: voltage_transformations: sample_rate: waveforms: These waveforms are sampled and stored in _waveforms. If None the waveforms are extracted from loop """ 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 if waveforms is None: waveforms = OrderedDict( (node.waveform, None) for node in loop.get_depth_first_iterator() if node.is_leaf()).keys() if waveforms: self._waveforms = OrderedDict( zip(waveforms, self._sample_waveforms(waveforms))) else: self._waveforms = OrderedDict()
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))
def register_program(self, name: str, program: Loop, run_callback=lambda: None, update=False) -> None: if not callable(run_callback): raise TypeError('The provided run_callback is not callable') channels = next( program.get_depth_first_iterator()).waveform.defined_channels if channels - set(self._channel_map.keys()): raise KeyError( 'The following channels are unknown to the HardwareSetup: {}'. format(channels - set(self._channel_map.keys()))) temp_measurement_windows = defaultdict(list) for mw_name, begins_lengths in program.get_measurement_windows().items( ): temp_measurement_windows[mw_name].append(begins_lengths) if set(temp_measurement_windows.keys()) - set( self._measurement_map.keys()): raise KeyError( 'The following measurements are not registered: {}\nUse set_measurement for that.' .format( set(temp_measurement_windows.keys()) - set(self._measurement_map.keys()))) measurement_windows = dict() while temp_measurement_windows: mw_name, begins_lengths_deque = temp_measurement_windows.popitem() begins, lengths = zip(*begins_lengths_deque) measurement_windows[mw_name] = (np.concatenate(begins), np.concatenate(lengths)) affected_dacs = defaultdict(dict) for measurement_name, begins_lengths in measurement_windows.items(): for dac, mask_name in self._measurement_map[measurement_name]: affected_dacs[dac][mask_name] = begins_lengths handled_awgs = set() awgs_to_channel_info = dict() def get_default_info(awg): return ([None] * awg.num_channels, [None] * awg.num_channels, [None] * awg.num_markers) for channel_id in channels: for single_channel in self._channel_map[channel_id]: playback_ids, voltage_trafos, marker_ids = \ awgs_to_channel_info.setdefault(single_channel.awg, get_default_info(single_channel.awg)) if isinstance(single_channel, PlaybackChannel): playback_ids[single_channel.channel_on_awg] = channel_id voltage_trafos[ single_channel. channel_on_awg] = single_channel.voltage_transformation elif isinstance(single_channel, MarkerChannel): marker_ids[single_channel.channel_on_awg] = channel_id for awg, (playback_ids, voltage_trafos, marker_ids) in awgs_to_channel_info.items(): if awg in handled_awgs: raise ValueError('AWG has two programs') else: handled_awgs.add(awg) awg.upload(name, program=program, channels=tuple(playback_ids), markers=tuple(marker_ids), force=update, voltage_transformation=tuple(voltage_trafos)) for dac, dac_windows in affected_dacs.items(): dac.register_measurement_windows(name, dac_windows) self._registered_programs[name] = RegisteredProgram( program=program, measurement_windows=measurement_windows, run_callback=run_callback, awgs_to_upload_to=handled_awgs, dacs_to_arm=set(affected_dacs.keys()))