Example #1
0
    def __init__(self,
                 name,
                 measurement_segment: segment_measurements,
                 segment_type='render'):
        '''
        Args:
            name (str): name of the segment usually the channel name
            segment_type (str) : type of the segment (e.g. 'render' --> to be rendered, 'virtual'--> no not render.)
        '''
        self.type = segment_type
        self.name = name
        self._measurement_segment = measurement_segment
        self._measurement_index = 0

        # store data in numpy looking object for easy operator access.
        self.data = data_container(acquisition_data())

        # local copy of self that will be used to count up the virtual gates.
        self._pulse_data_all = None
        # data caching variable. Used for looping and so on (with a decorator approach)
        self.data_tmp = None

        # setpoints of the loops (with labels and units)
        self._setpoints = setpoint_mgr()
        self.render_mode = False
    def __init__(self,
                 name,
                 data_object,
                 HVI_variable_data=None,
                 segment_type='render'):
        '''
        Args:
            name (str): name of the segment usually the channel name
            data_object (object) : class that is used for saving the data type.
            HVI_variable_data (segment_HVI_variables) : segment used to keep variables that can be used in HVI.
            segment_type (str) : type of the segment (e.g. 'render' --> to be rendered, 'virtual'--> no not render.)
        '''
        self.type = segment_type
        self.name = name
        self.render_mode = False
        # variable specifing the laetest change to the waveforms,
        self._last_edit = last_edit.ToRender

        # store data in numpy looking object for easy operator access.
        self.data = data_container(data_object)
        self._data_hvi_variable = HVI_variable_data

        # references to other channels (for virtual gates).
        self.reference_channels = []
        # reference channels for IQ virtual channels
        self.IQ_ref_channels = []
        self.references_markers = []
        # local copy of self that will be used to count up the virtual gates.
        self._pulse_data_all = None
        # data caching variable. Used for looping and so on (with a decorator approach)
        self.data_tmp = None
        # variable specifing the lastest time the pulse_data_all is updated

        # setpoints of the loops (with labels and units)
        self._setpoints = setpoint_mgr()
def _extend_dimensions(data, shape, use_ref):
    '''
    Extends the dimensions of a existing array object. This is useful if one would have first defined sweep axis 2 without defining axis 1.
    In this case axis 1 is implicitly made, only harbouring 1 element.
    This function can be used to change the axis 1 to a different size.

    Args:
        data (np.ndarray[dtype = object]) : numpy object that contains all the segment data of every iteration.
        shape (list/np.ndarray) : list of the new dimensions of the array (should have the same lenght as the dimension of the data!)
        use_ref (bool) : use pointer to copy, or take full copy (False is full copy)
    '''
    new_data = data_container(shape=shape)
    for i in range(len(shape)):
        if data.shape[i] != shape[i]:
            if i == 0:
                for j in range(len(new_data)):
                    new_data[j] = cpy_numpy_shallow(data, use_ref)
            else:
                new_data = new_data.swapaxes(i, 0)
                data = data.swapaxes(i, 0)

                for j in range(len(new_data)):
                    new_data[j] = cpy_numpy_shallow(data, use_ref)

                new_data = new_data.swapaxes(i, 0)

    return new_data
Example #4
0
    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)
Example #5
0
    def __getitem__(self, *key):
        '''
        get slice or single item of this segment (note no copying, just referencing)
        Args:
            *key (int/slice object) : key of the element -- just use numpy style accessing (slicing supported)
        '''
        item = copy.copy(self)
        item.data = data_container(self.data[key[0]])

        return item
def _add_dimensions(data, shape, use_ref):
    """
    Function that can be used to add and extra dimension of an array object. A seperate function is needed since we want to make a copy and not a reference.
    Note that only one dimension can be extended!
    Args:
        data (np.ndarray[dtype = object]) : numpy object that contains all the segment data of every iteration.
        shape (list/np.ndarray) : list of the new dimensions of the array
        use_ref (bool) : use pointer to copy, or take full copy (False is full copy)
    """
    new_data = data_container(shape=shape)
    for i in range(shape[0]):
        new_data[i] = cpy_numpy_shallow(data, use_ref)
    return new_data
Example #7
0
    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 __getitem__(self, *key):
        '''
        get slice or single item of this segment (note no copying, just referencing)
        Args:
            *key (int/slice object) : key of the element -- just use numpy style accessing (slicing supported)
        '''
        data_item = self.data[key[0]]
        if not isinstance(data_item, data_container):
            # If the slice contains only 1 element, then it's not a data_container anymore.
            # Put it in a data_container to maintain pulse_lib structure.
            data_item = data_container(data_item)

        # To avoid unnecessary copying of data we first slice on self, copy, and then restore data in self.
        # This trick makes the indexing operation orders faster.
        data_org = self.data
        self.data = data_item
        item = copy.copy(self)
        item.data = data_item  # TODO [SdS]: make clean solution
        self.data = data_org
        return item