def test_iterable_eq_fails_two_numpy_array(b): """ Test that different value and different length comparisons against numpy arrays fail """ a = numpy.array([1, 2, 3]) b = numpy.array(b) with pytest.raises(AssertionError): iterable_eq(a, b)
def test_iterable_eq_passes_two_numpy_array_quantities(): """ Test that two unitful quantities with numpy array data will equal data will pass """ values = [1, 2, 3] a = numpy.array(values) * u.V b = numpy.array(a) * u.V iterable_eq(a, b)
def test_take_measurement(): with expected_protocol( ik.srs.SRS830, [ "REST", "SRAT 4", "SEND 0", "FAST 2", "STRD", "PAUS", "SPTS?", "SPTS?", "TRCA?1,0,2", "SPTS?", "TRCA?2,0,2" ], [ "2", "2", "1.234,5.678", "2", "0.456,5.321" ] ) as inst: resp = inst.take_measurement(sample_rate=1, num_samples=2) expected = ((1.234, 5.678), (0.456, 5.321)) if numpy: expected = numpy.array(expected) iterable_eq(resp, expected)
def test_upload_waveform_type_mismatch(yzero, ymult, xincr, waveform): """Raise type error when types for method mismatched.""" wrong_type_yzero = "42" wrong_type_ymult = "42" wrong_type_xincr = "42" waveform_ndarray = numpy.array(waveform) with expected_protocol(ik.tektronix.TekAWG2000, [], []) as inst: # wrong yzero type with pytest.raises(TypeError) as exc_info: inst.upload_waveform(wrong_type_yzero, ymult, xincr, waveform_ndarray) exc_msg = exc_info.value.args[0] assert exc_msg == "yzero must be specified as a float or int" # wrong ymult type with pytest.raises(TypeError) as exc_info: inst.upload_waveform(yzero, wrong_type_ymult, xincr, waveform_ndarray) exc_msg = exc_info.value.args[0] assert exc_msg == "ymult must be specified as a float or int" # wrong xincr type with pytest.raises(TypeError) as exc_info: inst.upload_waveform(yzero, ymult, wrong_type_xincr, waveform_ndarray) exc_msg = exc_info.value.args[0] assert exc_msg == "xincr must be specified as a float or int" # wrong waveform type with pytest.raises(TypeError) as exc_info: inst.upload_waveform(yzero, ymult, xincr, waveform) exc_msg = exc_info.value.args[0] assert exc_msg == "waveform must be specified as a numpy array"
def test_maui_data_source_read_waveform(init): """Return a numpy array of a waveform.""" with expected_protocol( ik.teledyne.MAUI, [ init, 'TRMD?', 'TRMD SINGLE', "C1:INSPECT? 'SIMPLE'", "C1:INSPECT? 'HORIZ_OFFSET'", "C1:INSPECT? 'HORIZ_INTERVAL'", 'TRMD AUTO' ], [ 'AUTO', '" 1. 2. 3. 4. "', "HORIZ_OFFSET : 0. ", "HORIZ_INTERVAL : 2.5 " ], sep="\n" ) as osc: if numpy: expected_wf = numpy.array( [ [0., 2.5, 5., 7.5], [1., 2., 3., 4.] ] ) else: expected_wf = ( (0., 2.5, 5., 7.5), (1., 2., 3., 4.) ) actual_wf = osc.channel[0].read_waveform() iterable_eq(actual_wf, expected_wf)
def test_tektds224_data_source_read_waveform(): with expected_protocol( ik.tektronix.TekTDS224, [ "DAT:SOU?", "DAT:SOU CH2", "DAT:ENC RIB", "DATA:WIDTH?", "CURVE?", "WFMP:CH2:YOF?", "WFMP:CH2:YMU?", "WFMP:CH2:YZE?", "WFMP:XZE?", "WFMP:XIN?", "WFMP:CH2:NR_P?", "DAT:SOU CH1" ], [ "CH1", "2", # pylint: disable=no-member "#210" + bytes.fromhex("00000001000200030004").decode("utf-8") + "0", "1", "0", "0", "1", "5" ]) as tek: data = tuple(range(5)) if numpy: data = numpy.array([0, 1, 2, 3, 4]) (x, y) = tek.channel[1].read_waveform() iterable_eq(x, data) iterable_eq(y, data)
def test_iterable_eq_fails_one_numpy_array_equal_values(): """ Test failure for one is numpy array, other is not """ a = numpy.array([1, 2, 3]) b = (1, 2, 3) with pytest.raises(AssertionError): iterable_eq(a, b)
def test_upload_waveform_wrong_max(yzero, ymult, xincr, waveform): """Raise ValueError when waveform maximum is too large.""" waveform_wrong_max = numpy.array(waveform) waveform_wrong_max[0] = 42. with expected_protocol(ik.tektronix.TekAWG2000, [], []) as inst: with pytest.raises(ValueError) as exc_info: inst.upload_waveform(yzero, ymult, xincr, waveform_wrong_max) exc_msg = exc_info.value.args[0] assert exc_msg == "The max value for an element in waveform is 1."
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_channel_read_waveform(): """Read waveform of channel object.""" with expected_protocol( ik.rigol.RigolDS1000Series, [":WAV:DATA? CHAN2"], [b"#210" + bytes.fromhex("00000001000200030004") + b"0"]) as osc: expected = (0, 1, 2, 3, 4) if numpy: expected = numpy.array(expected) iterable_eq(osc.channel[1].read_waveform(), expected)
def test_instrument_binblockread(): with expected_protocol(ik.Instrument, [], [ b"#210" + bytes.fromhex("00000001000200030004") + b"0", ], sep="\n") as inst: actual_data = inst.binblockread(2) expected = (0, 1, 2, 3, 4) if numpy: expected = numpy.array(expected) iterable_eq(actual_data, expected)
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_channel_wavelength(values, channel): values_packed = b"".join(struct.pack("<d", 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.yokogawa.Yokogawa6370, [ ":FORMat:DATA REAL,64", ":TRAC:X? {}".format(channel.value), ], [b"#" + values_len_of_len + values_len + values_packed]) as inst: values = tuple(values) if numpy: values = numpy.array(values, dtype="<d") iterable_eq(inst.channel[channel].wavelength(), values)
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_agilent34410a_r(): with expected_protocol( ik.agilent.Agilent34410a, ["CONF?", "FORM:DATA REAL,64", "R? 1"], [ "VOLT +1.000000E+01,+3.000000E-06", # pylint: disable=no-member b"#18" + bytes.fromhex("3FF0000000000000") ]) as dmm: expected = (u.Quantity(1, u.volt), ) if numpy: expected = numpy.array([1]) * u.volt actual = dmm.r(1) iterable_eq(actual, expected)
def test_instrument_binblockread_two_reads(): inst = ik.Instrument.open_test() data = bytes.fromhex("00000001000200030004") inst._file.read_raw = mock.MagicMock( side_effect=[b"#", b"2", b"10", data[:6], data[6:]]) expected = (0, 1, 2, 3, 4) if numpy: expected = numpy.array((0, 1, 2, 3, 4)) iterable_eq(inst.binblockread(2), expected) calls_expected = [1, 1, 2, 10, 4] calls_actual = [call[0][0] for call in inst._file.read_raw.call_args_list] iterable_eq(calls_actual, calls_expected)
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_upload_waveform(yzero, ymult, xincr, waveform): """Upload a waveform from the PC to the instrument.""" # prep waveform waveform = numpy.array(waveform) waveform_send = waveform * (2**12 - 1) waveform_send = waveform_send.astype("<u2").tobytes() wfm_header_2 = str(len(waveform_send)) wfm_header_1 = len(wfm_header_2) bin_str = "#{}{}{}".format(wfm_header_1, wfm_header_2, waveform_send) with expected_protocol(ik.tektronix.TekAWG2000, [ f"WFMP:YZERO {yzero}", f"WFMP:YMULT {ymult}", f"WFMP:XINCR {xincr}", f"CURVE {bin_str}" ], []) as inst: inst.upload_waveform(yzero, ymult, xincr, waveform)
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 take_measurement(self, sample_rate, num_samples): """ Wrapper function that allows you to easily take measurements with a specified sample rate and number of desired samples. Function will call time.sleep() for the required amount of time it will take the instrument to complete this sampling operation. Returns a list containing two items, each of which are lists containing the channel data. The order is [[Ch1 data], [Ch2 data]]. :param `int` sample_rate: Set the desired sample rate of the measurement. See `~SRS830.sample_rate` for more information. :param `int` num_samples: Number of samples to take. :rtype: `tuple`[`tuple`[`float`, ...], `tuple`[`float`, ...]] or if numpy is installed, `numpy.array`[`numpy.array`, `numpy.array`] """ if num_samples > 16383: raise ValueError('Number of samples cannot exceed 16383.') sample_time = math.ceil(num_samples / sample_rate) self.init(sample_rate, SRS830.BufferMode['one_shot']) self.start_data_transfer() time.sleep(sample_time + 0.1) self.pause() # The following should fail. We do this to force the instrument # to flush its internal buffers. # Note that this causes a redundant transmission, and should be fixed # in future versions. try: self.num_data_points except IOError: pass ch1 = self.read_data_buffer('ch1') ch2 = self.read_data_buffer('ch2') if numpy: return numpy.array([ch1, ch2]) return ch1, ch2
def test_read_data_buffer_mode_as_str(): with expected_protocol( ik.srs.SRS830, [ "SPTS?", "TRCA?1,0,2" ], [ "2", "1.234,9.876" ] ) as inst: data = inst.read_data_buffer(channel="ch1") expected = (1.234, 9.876) if numpy: expected = numpy.array(expected) iterable_eq(data, expected)
def test_take_measurement_num_dat_points_fails(): """Simulate the failure of num_data_points. This is the way it is currently implemented. """ with expected_protocol( ik.srs.SRS830, [ "REST", "SRAT 4", "SEND 0", "FAST 2", "STRD", "PAUS" ] + [ "SPTS?" ] * 11 + [ "TRCA?1,0,2", "SPTS?", "TRCA?2,0,2" ], [ "", ] * 10 + [ "2", "1.234,5.678", "2", "0.456,5.321" ] ) as inst: resp = inst.take_measurement(sample_rate=1, num_samples=2) expected = ((1.234, 5.678), (0.456, 5.321)) if numpy: expected = numpy.array(expected) iterable_eq(resp, expected)
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)
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
def test_iterable_eq_passes_two_numpy_array(): """ Test pases for two identical numpy arrays """ a = numpy.array([1, 2, 3]) iterable_eq(a, a.copy())
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
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
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