Exemplo n.º 1
0
def test_maui_data_source_read_waveform_different_length(init):
    """BF: Stacking return arrays with different length.

    Depending on rounding issues, time and data arrays can have
    different lengths. Shorten to the shorter one by cutting the longer
    one from the end.
    """
    faulty_dataset_str = []
    faulty_dataset_int = []
    for it in range(402):  # 402 datapoints will make the error
        faulty_dataset_str.append(str(it))
        faulty_dataset_int.append(it)
    return_data_string = '"   ' + '   '.join(faulty_dataset_str) + '   "'

    with expected_protocol(
            ik.teledyne.MAUI,
            [
                init,
                'TRMD?',
                'TRMD SINGLE',
                "C1:INSPECT? 'SIMPLE'",
                "C1:INSPECT? 'HORIZ_OFFSET'",
                "C1:INSPECT? 'HORIZ_INTERVAL'",
                'TRMD AUTO'
            ],
            [
                'AUTO',
                return_data_string,
                "HORIZ_OFFSET       : 9.8895e-06   ",
                "HORIZ_INTERVAL     : 5e-10        "
            ],
            sep="\n"
    ) as osc:
        h_offset = 9.8895e-06
        h_interval = 5e-10

        if numpy:
            # create the signal that we want to get returned
            signal = numpy.array(faulty_dataset_int)
            timebase = numpy.arange(
                h_offset,
                h_offset + h_interval * (len(signal)),
                h_interval
            )

            # now cut timebase to the length of the signal
            timebase = timebase[0:len(signal)]
            # create return dataset
            dataset_return = numpy.stack((timebase, signal))
        else:
            signal = tuple(faulty_dataset_int)
            timebase = tuple([float(val) * h_interval + h_offset for val in range(len(signal))])
            timebase = timebase[0:len(signal)]
            dataset_return = timebase, signal

        actual_wf = osc.channel[0].read_waveform()
        iterable_eq(actual_wf, dataset_return)
def test_data_source_read_waveform_binary(values):
    """Read waveform from data source as binary."""
    # constants - to not overkill it with hypothesis
    channel_no = 0
    data_width = 2
    yoffs = 1.
    ymult = 1.
    yzero = 0.3
    xincr = 0.001
    # make values to compare with
    ptcnt = len(values)
    values_arr = values
    if numpy:
        values_arr = numpy.array(values)
    values_packed = b"".join(struct.pack(">h", value) for value in values)
    values_len = str(len(values_packed)).encode()
    values_len_of_len = str(len(values_len)).encode()

    # calculations
    if numpy:
        x_calc = numpy.arange(float(ptcnt)) * xincr
        y_calc = ((values_arr - yoffs) * ymult) + yzero
    else:
        x_calc = tuple([float(val) * float(xincr) for val in range(ptcnt)])
        y_calc = tuple(((val - yoffs) * float(ymult)) + float(yzero) for val in values)

    with expected_protocol(
            ik.tektronix.TekTDS5xx,
            [
                "DAT:SOU?",
                "DAT:ENC RIB",
                "DATA:WIDTH?",
                "CURVE?",
                f"WFMP:CH{channel_no+1}:YOF?",
                f"WFMP:CH{channel_no+1}:YMU?",
                f"WFMP:CH{channel_no+1}:YZE?",
                f"WFMP:CH{channel_no+1}:XIN?",
                f"WFMP:CH{channel_no+1}:NR_P?"

            ],
            [
                f"CH{channel_no+1}",
                f"{data_width}",
                b"#" + values_len_of_len + values_len + values_packed,
                f"{yoffs}",
                f"{ymult}",
                f"{yzero}",
                f"{xincr}",
                f"{ptcnt}"
            ]
    ) as inst:
        channel = inst.channel[channel_no]
        x_read, y_read = channel.read_waveform(bin_format=True)
        iterable_eq(x_read, x_calc)
        iterable_eq(y_read, y_calc)
def test_data_source_read_waveform_ascii(values, ymult, yzero, xzero, xincr):
    """Read waveform back in ASCII format."""
    old_dat_source = 3
    old_dat_stop = 100  # "previous" setting
    # new values
    channel = 0
    yoffs = 0  # already tested with hypothesis
    # transform values to strings
    values_str = ",".join([str(value) for value in values])
    # calculated values
    ptcnt = len(values)
    with expected_protocol(
            ik.tektronix.TekDPO4104,
        [
            "DAT:SOU?",  # old data source
            f"DAT:SOU CH{channel + 1}",
            "DAT:STOP?",
            f"DAT:STOP {10**7}",
            "DAT:ENC ASCI",  # set encoding
            "CURVE?",  # get the data (in bin format)
            "WFMP:YOF?",
            "WFMP:YMU?",  # query y-offset
            "WFMP:YZE?",  # query y zero
            "WFMP:XZE?",  # query x zero
            "WFMP:XIN?",  # retrieve x increments
            "WFMP:NR_P?",  # retrieve number of points
            f"DAT:STOP {old_dat_stop}",
            f"DAT:SOU CH{old_dat_source + 1}"  # set back old data source
        ],
        [
            f"CH{old_dat_source + 1}", f"{old_dat_stop}", f"{values_str}",
            f"{yoffs}", f"{ymult}", f"{yzero}", f"{xzero}", f"{xincr}",
            f"{ptcnt}"
        ]) as inst:
        # get the values from the instrument
        x_read, y_read = inst.channel[channel].read_waveform(bin_format=False)

        # manually calculate the values
        if numpy:
            raw = numpy.array(values_str.split(","), dtype=numpy.float)
            x_calc = numpy.arange(ptcnt) * xincr + xzero
            y_calc = (raw - yoffs) * ymult + yzero
        else:
            x_calc = tuple(
                [float(val) * xincr + xzero for val in range(ptcnt)])
            y_calc = tuple([((float(val) - yoffs) * ymult) + yzero
                            for val in values])

        # assert arrays are equal
        iterable_eq(x_read, x_calc)
        iterable_eq(y_read, y_calc)
def test_data_source_read_waveform_ascii(values):
    """Read waveform from data source as ASCII."""
    # constants - to not overkill it with hypothesis
    channel_no = 0
    yoffs = 1.
    ymult = 1.
    yzero = 0.3
    xincr = 0.001
    # make values to compare with
    values_str = ",".join([str(value) for value in values])
    values_arr = values
    if numpy:
        values_arr = numpy.array(values)

    # calculations
    ptcnt = len(values)
    if numpy:
        x_calc = numpy.arange(float(ptcnt)) * xincr
        y_calc = ((values_arr - yoffs) * ymult) + yzero
    else:
        x_calc = tuple([float(val) * float(xincr) for val in range(ptcnt)])
        y_calc = tuple(((val - yoffs) * float(ymult)) + float(yzero) for val in values)

    with expected_protocol(
            ik.tektronix.TekTDS5xx,
            [
                "DAT:SOU?",
                "DAT:ENC ASCI",
                "CURVE?",
                f"WFMP:CH{channel_no+1}:YOF?",
                f"WFMP:CH{channel_no+1}:YMU?",
                f"WFMP:CH{channel_no+1}:YZE?",
                f"WFMP:CH{channel_no+1}:XIN?",
                f"WFMP:CH{channel_no+1}:NR_P?"

            ],
            [
                f"CH{channel_no+1}",
                values_str,
                f"{yoffs}",
                f"{ymult}",
                f"{yzero}",
                f"{xincr}",
                f"{ptcnt}"
            ]
    ) as inst:
        channel = inst.channel[channel_no]
        x_read, y_read = channel.read_waveform(bin_format=False)
        iterable_eq(x_read, x_calc)
        iterable_eq(y_read, y_calc)
def test_data_source_read_waveform_bin(values, ymult, yzero, xzero, xincr):
    """Read the waveform of a data trace in bin format."""
    old_dat_source = 3
    old_dat_stop = 100  # "previous" setting
    # new values
    channel = 0
    data_width = 2  # use format '>h' for decoding
    yoffs = 0  # already tested with hypothesis
    # values packing
    ptcnt = len(values)
    values_packed = b"".join(struct.pack(">h", value) for value in values)
    values_len = str(len(values_packed)).encode()
    values_len_of_len = str(len(values_len)).encode()
    with expected_protocol(
            ik.tektronix.TekDPO4104,
        [
            "DAT:SOU?",  # old data source
            f"DAT:SOU CH{channel+1}",
            "DAT:STOP?",
            f"DAT:STOP {10**7}",
            "DAT:ENC RIB",  # set encoding
            "DATA:WIDTH?",  # query data width
            "CURVE?",  # get the data (in bin format)
            "WFMP:YOF?",  # query yoffs
            "WFMP:YMU?",  # query ymult
            "WFMP:YZE?",  # query yzero
            "WFMP:XZE?",  # query x zero
            "WFMP:XIN?",  # retrieve x increments
            "WFMP:NR_P?",  # retrieve number of points
            f"DAT:STOP {old_dat_stop}",
            f"DAT:SOU CH{old_dat_source + 1}"  # set back old data source
        ],
        [
            f"CH{old_dat_source+1}", f"{old_dat_stop}", f"{data_width}",
            b"#" + values_len_of_len + values_len + values_packed, f"{yoffs}",
            f"{ymult}", f"{yzero}", f"{xzero}", f"{xincr}", f"{ptcnt}"
        ],
    ) as inst:
        x_read, y_read = inst.channel[channel].read_waveform()
        if numpy:
            x_calc = numpy.arange(ptcnt) * xincr + xzero
            y_calc = ((numpy.array(values) - yoffs) * ymult) + yzero
        else:
            x_calc = tuple(
                [float(val) * xincr + xzero for val in range(ptcnt)])
            y_calc = tuple([((float(val) - yoffs) * ymult) + yzero
                            for val in values])
        iterable_eq(x_read, x_calc)
        iterable_eq(y_read, y_calc)
def test_tektds224_data_source_read_waveform_ascii(values):
    """Read waveform as ASCII"""
    # values
    values_str = ",".join([str(value) for value in values])

    # parameters
    yoffs = 1
    ymult = 1
    yzero = 0
    xzero = 0
    xincr = 1
    ptcnt = len(values)

    with expected_protocol(ik.tektronix.TekTDS224, [
            "DAT:SOU?", "DAT:SOU CH2", "DAT:ENC ASCI", "CURVE?",
            "WFMP:CH2:YOF?", "WFMP:CH2:YMU?", "WFMP:CH2:YZE?", "WFMP:XZE?",
            "WFMP:XIN?", "WFMP:CH2:NR_P?", "DAT:SOU CH1"
    ], [
            "CH1", values_str, f"{yoffs}", f"{ymult}", f"{yzero}", f"{xzero}",
            f"{xincr}", f"{ptcnt}"
    ]) as tek:
        if numpy:
            x_expected = numpy.arange(
                float(ptcnt)) * float(xincr) + float(xzero)
            y_expected = ((numpy.array(values) - float(yoffs)) *
                          float(ymult)) + float(yzero)
        else:
            x_expected = tuple([
                float(val) * float(xincr) + float(xzero)
                for val in range(ptcnt)
            ])
            y_expected = tuple([
                ((val - float(yoffs)) * float(ymult)) + float(yzero)
                for val in values
            ])
        x_read, y_read = tek.channel[1].read_waveform(bin_format=False)
        iterable_eq(x_read, x_expected)
        iterable_eq(y_read, y_expected)
Exemplo n.º 7
0
    def read_waveform(self, bin_format=True):
        """
        Read waveform from the oscilloscope.
        This function is all inclusive. After reading the data from the
        oscilloscope, it unpacks the data and scales it accordingly.

        Supports both ASCII and binary waveform transfer. For 2500 data
        points, with a width of 2 bytes, transfer takes approx 2 seconds for
        binary, and 7 seconds for ASCII over Galvant Industries' GPIBUSB
        adapter.

        Function returns a tuple (x,y), where both x and y are numpy arrays.

        :param bool bin_format: If `True`, data is transfered
            in a binary format. Otherwise, data is transferred in ASCII.

        :rtype: `tuple`[`tuple`[`float`, ...], `tuple`[`float`, ...]]
            or if numpy is installed, `tuple`[`numpy.array`, `numpy.array`]
        """
        with self:

            if not bin_format:
                self._tek.sendcmd("DAT:ENC ASCI")
                # Set the data encoding format to ASCII
                raw = self._tek.query("CURVE?")
                raw = raw.split(',')  # Break up comma delimited string
                if numpy:
                    raw = numpy.array(raw,
                                      dtype=numpy.float)  # Convert to ndarray
                else:
                    raw = tuple(map(float, raw))
            else:
                self._tek.sendcmd("DAT:ENC RIB")
                # Set encoding to signed, big-endian
                data_width = self._tek.data_width
                self._tek.sendcmd("CURVE?")
                raw = self._tek.binblockread(
                    data_width)  # Read in the binary block,
                # data width of 2 bytes

                # pylint: disable=protected-access
                self._tek._file.flush_input()  # Flush input buffer

            yoffs = self._tek.query(
                f"WFMP:{self.name}:YOF?")  # Retrieve Y offset
            ymult = self._tek.query(
                f"WFMP:{self.name}:YMU?")  # Retrieve Y multiply
            yzero = self._tek.query(
                f"WFMP:{self.name}:YZE?")  # Retrieve Y zero

            xzero = self._tek.query("WFMP:XZE?")  # Retrieve X zero
            xincr = self._tek.query("WFMP:XIN?")  # Retrieve X incr
            ptcnt = self._tek.query(
                f"WFMP:{self.name}:NR_P?")  # Retrieve number of data points

            if numpy:
                x = numpy.arange(float(ptcnt)) * float(xincr) + float(xzero)
                y = ((raw - float(yoffs)) * float(ymult)) + float(yzero)
            else:
                x = tuple(
                    float(val) * float(xincr) + float(xzero)
                    for val in range(int(ptcnt)))
                y = tuple(((x - float(yoffs)) * float(ymult)) + float(yzero)
                          for x in raw)

            return x, y
Exemplo n.º 8
0
    def read_waveform(self, bin_format=True):
        """
        Read waveform from the oscilloscope.
        This function is all inclusive. After reading the data from the
        oscilloscope, it unpacks the data and scales it accordingly.

        Supports both ASCII and binary waveform transfer. For 2500 data
        points, with a width of 2 bytes, transfer takes approx 2 seconds for
        binary, and 7 seconds for ASCII over Galvant Industries' GPIBUSB
        adapter.

        Function returns a tuple (x,y), where both x and y are numpy arrays.

        :param bool bin_format: If `True`, data is transfered
            in a binary format. Otherwise, data is transferred in ASCII.

        :rtype: `tuple`[`tuple`[`float`, ...], `tuple`[`float`, ...]]
            or if numpy is installed, `tuple`[`numpy.array`, `numpy.array`]
        """
        with self:

            if not bin_format:
                # Set the data encoding format to ASCII
                self._parent.sendcmd('DAT:ENC ASCI')
                raw = self._parent.query('CURVE?')
                raw = raw.split(',')  # Break up comma delimited string
                if numpy:
                    raw = numpy.array(raw, dtype=numpy.float)  # Convert to numpy array
                else:
                    raw = map(float, raw)
            else:
                # Set encoding to signed, big-endian
                self._parent.sendcmd('DAT:ENC RIB')
                data_width = self._parent.data_width
                self._parent.sendcmd('CURVE?')
                # Read in the binary block, data width of 2 bytes
                raw = self._parent.binblockread(data_width)

                # pylint: disable=protected-access
                # read line separation character
                self._parent._file.read_raw(1)

            # Retrieve Y offset
            yoffs = float(self._parent.query('WFMP:{}:YOF?'.format(self.name)))
            # Retrieve Y multiply
            ymult = float(self._parent.query('WFMP:{}:YMU?'.format(self.name)))
            # Retrieve Y zero
            yzero = float(self._parent.query('WFMP:{}:YZE?'.format(self.name)))

            # Retrieve X incr
            xincr = float(self._parent.query('WFMP:{}:XIN?'.format(self.name)))
            # Retrieve number of data points
            ptcnt = int(self._parent.query('WFMP:{}:NR_P?'.format(self.name)))

            if numpy:
                x = numpy.arange(float(ptcnt)) * float(xincr)
                y = ((raw - yoffs) * float(ymult)) + float(yzero)
            else:
                x = tuple([float(val) * float(xincr) for val in range(ptcnt)])
                y = tuple(((x - yoffs) * float(ymult)) + float(yzero) for x in raw)

            return x, y
Exemplo n.º 9
0
    def read_waveform(self, bin_format=True):
        """
        Read waveform from the oscilloscope.
        This function is all inclusive. After reading the data from the
        oscilloscope, it unpacks the data and scales it accordingly.
        Supports both ASCII and binary waveform transfer.

        Function returns a tuple (x,y), where both x and y are numpy arrays.

        :param bool bin_format: If `True`, data is transfered
            in a binary format. Otherwise, data is transferred in ASCII.
        :rtype: `tuple`[`tuple`[`~pint.Quantity`, ...], `tuple`[`~pint.Quantity`, ...]]
            or if numpy is installed, `tuple` of two `~pint.Quantity` with `numpy.array` data
        """

        # Set the acquisition channel
        with self:

            # TODO: move this out somewhere more appropriate.
            old_dat_stop = self._tek.query("DAT:STOP?")
            self._tek.sendcmd("DAT:STOP {}".format(10**7))

            if not bin_format:
                # Set data encoding format to ASCII
                self._tek.sendcmd("DAT:ENC ASCI")
                sleep(0.02)  # Work around issue with 2.48 firmware.
                raw = self._tek.query("CURVE?")
                raw = raw.split(",")  # Break up comma delimited string
                if numpy:
                    raw = numpy.array(raw, dtype=numpy.float)  # Convert to numpy array
                else:
                    raw = map(float, raw)
            else:
                # Set encoding to signed, big-endian
                self._tek.sendcmd("DAT:ENC RIB")
                sleep(0.02)  # Work around issue with 2.48 firmware.
                data_width = self._tek.data_width
                self._tek.sendcmd("CURVE?")
                # Read in the binary block, data width of 2 bytes.
                raw = self._tek.binblockread(data_width)
                # Read the new line character that is sent
                self._tek._file.read_raw(1)  # pylint: disable=protected-access

            yoffs = self._tek.y_offset  # Retrieve Y offset
            ymult = self._tek.query("WFMP:YMU?")  # Retrieve Y multiplier
            yzero = self._tek.query("WFMP:YZE?")  # Retrieve Y zero

            xzero = self._tek.query("WFMP:XZE?")  # Retrieve X zero
            xincr = self._tek.query("WFMP:XIN?")  # Retrieve X incr
            # Retrieve number of data points
            ptcnt = self._tek.query("WFMP:NR_P?")

            if numpy:
                x = numpy.arange(float(ptcnt)) * float(xincr) + float(xzero)
                y = ((raw - yoffs) * float(ymult)) + float(yzero)
            else:
                x = tuple([float(val) * float(xincr) + float(xzero) for val in range(int(ptcnt))])
                y = tuple(((x - yoffs) * float(ymult)) + float(yzero) for x in raw)

            self._tek.sendcmd("DAT:STOP {}".format(old_dat_stop))

            return x, y
Exemplo n.º 10
0
        def read_waveform(self, bin_format=False, single=True):
            """
            Reads the waveform and returns an array of floats with the
            data.

            :param bin_format: Not implemented, always False
            :type bin_format: bool
            :param single: Run a single trigger? Default True. In case
                a waveform from a channel is required, this option
                is recommended to be set to True. This means that the
                acquisition system is first stopped, a single trigger
                is issued, then the waveform is transfered, and the
                system is set back into the state it was in before.
                If sampling math with multiple samples, set this to
                false, otherwise the sweeps are cleared by the
                oscilloscope prior when a single trigger command is
                issued.
            :type single: bool

            :return: Data (time, signal) where time is in seconds and
                signal in V
            :rtype: `tuple`[`tuple`[`~pint.Quantity`, ...], `tuple`[`~pint.Quantity`, ...]]
                or if numpy is installed, `tuple`[`numpy.array`, `numpy.array`]

            :raises NotImplementedError: Bin format was chosen, but
                it is not implemented.

            Example usage:
                >>> import instruments as ik
                >>> import instruments.units as u
                >>> inst = ik.teledyne.MAUI.open_visa("TCPIP0::192.168.0.10::INSTR")
                >>> channel = inst.channel[0]  # set up channel
                >>> xdat, ydat = channel.read_waveform()  # read waveform
            """
            if bin_format:
                raise NotImplementedError("Bin format reading is currently "
                                          "not implemented for the MAUI "
                                          "routine.")

            if single:
                # get current trigger state (to reset after read)
                trig_state = self._parent.trigger_state
                # trigger state to single
                self._parent.trigger_state = self._parent.TriggerState.single

            # now read the data
            retval = self.query("INSPECT? 'SIMPLE'")  # pylint: disable=E1101

            # read the parameters to create time-base array
            horiz_off = self.query("INSPECT? 'HORIZ_OFFSET'")  # pylint: disable=E1101
            horiz_int = self.query("INSPECT? 'HORIZ_INTERVAL'")  # pylint: disable=E1101

            if single:
                # reset trigger
                self._parent.trigger_state = trig_state

            # format the string to appropriate data
            retval = retval.replace('"', '').split()
            if numpy:
                dat_val = numpy.array(retval, dtype=numpy.float)  # Convert to ndarray
            else:
                dat_val = tuple(map(float, retval))

            # format horizontal data into floats
            horiz_off = float(horiz_off.replace('"', '').split(':')[1])
            horiz_int = float(horiz_int.replace('"', '').split(':')[1])

            # create time base
            if numpy:
                dat_time = numpy.arange(
                    horiz_off,
                    horiz_off + horiz_int * (len(dat_val)),
                    horiz_int
                )
            else:
                dat_time = tuple(val * horiz_int + horiz_off for val in range(len(dat_val)))

            # fix length bug, sometimes dat_time is longer than dat_signal
            if len(dat_time) > len(dat_val):
                dat_time = dat_time[0:len(dat_val)]
            else:  # in case the opposite is the case
                dat_val = dat_val[0:len(dat_time)]

            if numpy:
                return numpy.stack((dat_time, dat_val))
            else:
                return dat_time, dat_val