def extend_dim(self, shape=None, ref=False): ''' extend the dimensions of the waveform to a given shape. Args: shape (tuple) : shape of the new waveform ref (bool) : put to True if you want to extend the dimension by using pointers instead of making full copies. If referencing is True, a pre-render will already be performed to make sure nothing is rendered double. ''' if shape is None: shape = self.shape for i in self.channels: if self.render_mode == False: getattr(self, i).data = update_dimension( getattr(self, i).data, shape, ref) if getattr(self, i).type == 'render' and self.render_mode == True: getattr(self, i)._pulse_data_all = update_dimension( getattr(self, i)._pulse_data_all, shape, ref) if self.render_mode == False: self._software_markers.data = update_dimension( self._software_markers.data, shape, ref) else: self._software_markers._pulse_data_all = update_dimension( self._software_markers.pulse_data_all, shape, ref)
def pulse_data_all(self): ''' pulse data object that contains the counted op data of all the reference channels (e.g. IQ and virtual gates). ''' if self.last_edit == last_edit.ToRender or self._pulse_data_all is None: self._pulse_data_all = copy.copy(self.data) for ref_chan in self.reference_channels: # make sure both have the same size. my_shape = find_common_dimension(self._pulse_data_all.shape, ref_chan.segment.shape) self._pulse_data_all = update_dimension( self._pulse_data_all, my_shape) self._pulse_data_all += ref_chan.segment.pulse_data_all * ref_chan.multiplication_factor ref_chan.segment._last_edit = last_edit.Rendered for ref_chan in self.IQ_ref_channels: my_shape = find_common_dimension( self._pulse_data_all.shape, ref_chan.virtual_channel.shape) self._pulse_data_all = update_dimension( self._pulse_data_all, my_shape) self._pulse_data_all += ref_chan.virtual_channel.get_IQ_data( ref_chan) for ref_chan in self.references_markers: my_shape = find_common_dimension(self._pulse_data_all.shape, ref_chan.IQ_channel_ptr.shape) self._pulse_data_all = update_dimension( self._pulse_data_all, my_shape) self._pulse_data_all += ref_chan.IQ_channel_ptr.get_marker_data( ) self._last_edit = last_edit.Rendered return self._pulse_data_all
def save_segment(segments, location, idx=0): if not isinstance(segments, list): segments = [segments] os.mkdir(location) for seg_number in range(len(segments)): os.mkdir(location + f'_{seg_number}/') _shape = (1, ) segments[seg_number].enter_rendering_mode() _shape = find_common_dimension(segments[seg_number].shape, _shape) for ch_name in segments[seg_number].channels: data = update_dimension( getattr(segments[seg_number], ch_name)._pulse_data_all, _shape, True) setattr(getattr(segments[seg_number], ch_name), '_pulse_data_all', data) for ch_name in segments[seg_number].channels: ch = getattr(seg, ch_name) pulse_data_curr_seg = ch.pulse_data_all.flat[idx] sample_rate = 1e9 y = pulse_data_curr_seg.render(sample_rate) x = np.linspace(0, pulse_data_curr_seg.total_time, y.size) np.save(f'{location}_{seg_number}/{ch_name}', np.asarray([x, y]))
def add_sequence(self, sequence): ''' Adds a sequence to this object. Args: sequence (array) : array of segment_container ''' # check input for entry in sequence: if isinstance( entry, pulse_lib.segments.segment_container.segment_container): self.sequence.append(entry) else: raise ValueError( 'The provided element in the sequence seems to be of the wrong data type. {} provided, segment_container expected' .format(type(entry))) # update dimensionality of all sequence objects for seg_container in self.sequence: seg_container.enter_rendering_mode() self._shape = find_common_dimension(seg_container.shape, self._shape) # Set the waveform cache equal to the the sum of the length of all axis of all channels. # The cache will than be big enough for 1D iterations along every axis. This gives best performance total_axis_length = 0 for seg_container in self.sequence: for channel_name in seg_container.channels: shape = getattr(seg_container, channel_name).data.shape total_axis_length += sum(shape) parent_data.set_waveform_cache_size(total_axis_length) self._shape = tuple(self._shape) self._sweep_index = [0] * self.ndim self._HVI_variables = data_container(marker_HVI_variable()) self._HVI_variables = update_dimension(self._HVI_variables, self.shape) # enforce master clock for the current segments (affects the IQ channels (translated into a phase shift) and and the marker channels (time shifts)) t_tot = np.zeros(self.shape) for seg_container in self.sequence: seg_container.extend_dim(self._shape, ref=True) lp_time = loop_obj(no_setpoints=True) lp_time.add_data(t_tot, axis=list(range(self.ndim - 1, -1, -1))) seg_container.add_master_clock(lp_time) self._HVI_variables += seg_container._software_markers.pulse_data_all t_tot += seg_container.total_time self.params = [] for i in range(len(self.labels)): par_name = self.labels[i] set_param = index_param(par_name, self, dim=i) self.params.append(set_param) setattr(self, par_name, set_param)
def __add__(self, other): ''' define addition operator for segment_single ''' new_segment = copy.copy(self) if isinstance(other, segment_base): shape1 = new_segment.data.shape shape2 = other.data.shape new_shape = get_union_of_shapes(shape1, shape2) other_data = update_dimension(other.data, new_shape) new_segment.data = update_dimension(new_segment.data, new_shape) new_segment.data += other_data elif type(other) == int or type(other) == float: new_segment.data += other else: raise TypeError("Please add up segment_single type or a number ") return new_segment
def pulse_data_all(self): ''' pulse data object that contains the counted op data of all the reference channels (e.g. IQ and virtual gates). ''' if self.last_edit == last_edit.ToRender or self._pulse_data_all is None: self._pulse_data_all = copy.copy(self.data) for ref_chan in self.reference_channels: # make sure both have the same size. my_shape = find_common_dimension(self._pulse_data_all.shape, ref_chan.segment.shape) self._pulse_data_all = update_dimension( self._pulse_data_all, my_shape) ref_chan.data = update_dimension(ref_chan.segment.data, my_shape) self._pulse_data_all += ref_chan.segment.data * ref_chan.multiplication_factor ref_chan.segment._last_edit = last_edit.Rendered for ref_chan in self.IQ_ref_channels: # todo -- update dim functions my_shape = find_common_dimension( self._pulse_data_all.shape, ref_chan. virtual_channel_pointer.shape) # Luca modification self._pulse_data_all = update_dimension( self._pulse_data_all, my_shape) # Luca modification self._pulse_data_all += ref_chan.virtual_channel_pointer.get_IQ_data( ref_chan.LO, ref_chan.IQ_render_option, ref_chan.image_render_option) for ref_chan in self.references_markers: my_shape = find_common_dimension( self._pulse_data_all.shape, ref_chan.IQ_channel_ptr.shape) # Luca modification self._pulse_data_all = update_dimension( self._pulse_data_all, my_shape) # Luca modification self._pulse_data_all += ref_chan.IQ_channel_ptr.get_marker_data( ref_chan.pre_delay, ref_chan.post_delay) self._last_edit = last_edit.Rendered return self._pulse_data_all
def get_marker_data(self, pre_delay, post_delay): ''' generate markers for the PM of the IQ modulation ''' my_marker_data = update_dimension(data_container(marker_data()), self.shape) my_marker_data = my_marker_data.flatten() # make a flat reference. local_data = self.data.flatten() for i in range(len(local_data)): for MW_pulse_info in local_data[i].MW_pulse_data: my_marker_data[i].add_marker(MW_pulse_info.start - pre_delay, MW_pulse_info.stop + post_delay) my_marker_data = my_marker_data.reshape(self.shape) return my_marker_data
def plot_seg(segments, idx=0, multi_dim=False): ''' plot all the segments that are operated in a segment, if looped, also plot some parts of the loop. Args: segments (pulse_container_combined) : segment to plot multi_dim (bool) : detects if there are loop/multiple dimenions in the pulse and plots them. #TODO ''' plt.figure() if not isinstance(segments, list): segments = [segments] data_x = dict() data_y = dict() for ch_name in segments[0].channels: data_x[ch_name] = list() data_y[ch_name] = list() _shape = (1, ) for seg_container in segments: seg_container.enter_rendering_mode() _shape = find_common_dimension(seg_container.shape, _shape) for seg_container in segments: for ch_name in segments[0].channels: data = update_dimension( getattr(seg_container, ch_name)._pulse_data_all, _shape, True) setattr(getattr(seg_container, ch_name), '_pulse_data_all', data) for ch_name in segments[0].channels: for seg in segments: ch = getattr(seg, ch_name) pulse_data_curr_seg = ch.pulse_data_all.flat[idx] sample_rate = 1e9 data_y[ch_name].append(pulse_data_curr_seg.render(sample_rate)) # offset = 0 # if len(data_x[ch_name]) != 0: # print(ch_name) # offset = data_x[ch_name][-1][-1] data_x[ch_name].append( np.linspace(0, pulse_data_curr_seg.total_time, len(data_y[ch_name][-1]))) data_x_concatenated = dict() data_y_concatenated = dict() for ch_name in segments[0].channels: data_x_concatenated[ch_name] = np.asarray([]) data_y_concatenated[ch_name] = np.asarray([]) for i in range(len(segments)): data_x_concatenated[ch_name] = np.concatenate( (data_x_concatenated[ch_name], data_x[ch_name][i])) data_y_concatenated[ch_name] = np.concatenate( (data_y_concatenated[ch_name], data_y[ch_name][i])) plt.plot(data_x_concatenated[ch_name], data_y_concatenated[ch_name], label=ch_name) plt.xlabel("time (ns)") plt.ylabel("amplitude (mV)") plt.legend() plt.show()