def append(self, other, time=None):
        '''
        append other segments the the current ones in the container.
        Args:
            other (segment_container) : other segment to append
        '''
        if not isinstance(other, segment_container):
            raise TypeError(
                "segment_container object expected. Did you supply a single segment?"
            )

        # make sure all object have a full size.
        my_shape = find_common_dimension(self.shape, other.shape)
        other.extend_dim(my_shape)
        self.extend_dim(my_shape)

        self._setpoints += other._setpoints

        if time == None:
            times = self.total_time

            time = lp.loop_obj(no_setpoints=True)
            time.add_data(times, list(range(len(times.shape) - 1, -1, -1)))
        for i in self.channels:
            segment = getattr(self, i)
            segment.append(getattr(other, i), time)
    def reset_time(self, extend_only=False):
        '''
        Args:
            extend_only (bool) : will just extend the time in the segment and not reset it if set to true [do not use when composing wavoforms...].

        Allings all segments togeter and sets the input time to 0,
        e.g. ,
        chan1 : waveform until 70 ns
        chan2 : waveform until 140ns
        -> totaltime will be 140 ns,
        when you now as a new pulse (e.g. at time 0, it will actually occur at 140 ns in both blocks)
        '''

        n_channels = len(self.channels)
        shape = list(self.shape)
        time_data = np.empty([n_channels] + shape)

        for i in range(len(self.channels)):
            time_data[i] = upconvert_dimension(
                getattr(self, self.channels[i]).total_time, shape)

        times = np.amax(time_data, axis=0)
        times, axis = reduce_arr(times)
        if len(axis) == 0:
            loop_obj = times
        else:
            loop_obj = lp.loop_obj(no_setpoints=True)
            loop_obj.add_data(times, axis)

        for i in self.channels:
            segment = getattr(self, i)
            segment.reset_time(loop_obj, False)
    def reset_time(self, extend_only=False):
        '''
        Args:
            extend_only (bool) : will just extend the time in the segment and not reset it if set to true [do not use when composing wavoforms...].

        Allings all segments togeter and sets the input time to 0,
        e.g. ,
        chan1 : waveform until 70 ns
        chan2 : waveform until 140ns
        -> totaltime will be 140 ns,
        when you now as a new pulse (e.g. at time 0, it will actually occur at 140 ns in both blocks)
        '''
        n_branches = len(self.branches)
        n_channels = len(self.branches[0].channels)
        shape = list(self.shape)
        time_data = np.empty([n_branches * n_channels] + shape)

        for ibranch, branch in enumerate(self.branches):
            for ich, ch in enumerate(branch.channels):
                time_data[ibranch * n_channels + ich] = upconvert_dimension(
                    branch[ch].total_time, shape)

        times = np.amax(time_data, axis=0)
        times, axis = reduce_arr(times)
        logging.info(f'times {times}')
        if len(axis) == 0:
            loop_obj = times
        else:
            loop_obj = lp.loop_obj(no_setpoints=True)
            loop_obj.add_data(times, axis)

        for branch in self.branches:
            for ch in branch.channels:
                branch[ch].reset_time(loop_obj, False)
def generate_state_tomography(segment, *qubits, repeat=1, axis=0):
    '''
    perform a state tomography on the given qubits

    Args:
        segment (segment_container) : container of the segments
        *qubits  (single_qubit_gate_spec) : gate spec of the qubits to be targetted
        axis (int) : axis where this tomography should run on
    '''
    m_operators = generate_measurement_operators(len(qubits)) * repeat
    setpoint = loop_obj()
    setpoint.add_data(np.linspace(1, len(m_operators), len(m_operators)),
                      axis=axis,
                      labels='State Tomography projection',
                      units='#')

    for i in range(len(qubits)):
        getattr(segment, qubits[i].qubit).update_dim(setpoint)

    # todo generalize
    for i in range(setpoint.data.size):
        gates = m_operators[i].split('_')

        for j in range(len(qubits)):
            qubits[j].load_std_gate(
                getattr(segment, qubits[j].qubit)[i], gates[j])
def to_loop_obj(oiginal, shape, loop_axis, l, u, s):
    looper = loop_obj()
    looper.add_data(upsize(oiginal, shape),
                    axis=loop_axis[::-1],
                    labels=l,
                    units=u,
                    setvals=tuple(s))
    return looper
示例#6
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)
示例#7
0
    def add_HVI_marker(self, marker_name, t_off=0):
        '''
        Add a HVI marker that corresponds to the current time of the segment (defined by reset_time).

        Args:
            marker_name (str) : name of the marker to add
            t_off (str) : offset to be given from the marker
        '''
        times = loop_obj(no_setpoints=True)
        times.add_data(self.data.start_time,
                       axis=list(range(self.data.ndim - 1, -1, -1)))

        self.add_HVI_variable(marker_name, times + t_off, True)
def get_allXY_specs(repeat):
    allXY_set = repeat * [['I', 'I'], ['X2', 'X2'], ['Y2', 'Y2'], ['X2', 'Y2'],
                          ['Y2', 'X2'], ['X', 'I'], ['Y', 'I'], ['X', 'Y'],
                          ['X', 'Y'], ['X', 'Y2'], ['Y', 'X2'], ['X2', 'Y'],
                          ['Y2', 'X'], ['X', 'X2'], ['X2', 'X'], ['Y', 'Y2'],
                          ['Y2', 'Y'], ['X2', 'I'], ['Y2', 'I'], ['X', 'X'],
                          ['Y', 'Y']]
    setpoint = loop_obj()

    setpoint.add_data(np.linspace(1, len(allXY_set), len(allXY_set)),
                      axis=0,
                      labels='ALL XY gate id',
                      units='#')
    return allXY_set, setpoint
示例#9
0
    def append(self, other, time=None):
        '''
        Put the other segment behind this one.
        Args:
            other (segment_single) : the segment to be appended
            time (double/loop_obj) : attach at the given time (if None, append at total_time of the segment)

        A time reset will be done after the other segment is added.
        TODO: transfer of units
        '''
        other_loopobj = loop_obj()
        other_loopobj.add_data(other.data,
                               axis=list(range(other.data.ndim - 1, -1, -1)))
        self._setpoints += other._setpoints
        self.__append(other_loopobj, time)

        return self