Skip to content

Commit

Permalink
Merge d6852c1 into 8d78c16
Browse files Browse the repository at this point in the history
  • Loading branch information
scasagrande committed Oct 29, 2020
2 parents 8d78c16 + d6852c1 commit 0e77a5f
Show file tree
Hide file tree
Showing 32 changed files with 538 additions and 247 deletions.
10 changes: 8 additions & 2 deletions instruments/abstract_instruments/instrument.py
Expand Up @@ -10,11 +10,15 @@
import os
import collections
import socket
import struct
import urllib.parse as parse

from serial import SerialException
from serial.tools.list_ports import comports
import numpy as np
try:
import numpy
except ImportError:
numpy = None
import pyvisa
import usb
import usb.core
Expand Down Expand Up @@ -285,7 +289,9 @@ def binblockread(self, data_width, fmt=None):
raise IOError("Did not read in the required number of bytes"
"during binblock read. Got {}, expected "
"{}".format(len(data), num_of_bytes))
return np.frombuffer(data, dtype=fmt)
if numpy:
return numpy.frombuffer(data, dtype=fmt)
return struct.unpack(f"{fmt[0]}{int(len(data)/data_width)}{fmt[-1]}", data)

# CLASS METHODS #

Expand Down
24 changes: 20 additions & 4 deletions instruments/agilent/agilent34410a.py
Expand Up @@ -6,6 +6,11 @@

# IMPORTS #####################################################################

try:
import numpy
except ImportError:
numpy = None

from instruments.generic_scpi import SCPIMultimeter
from instruments.units import ureg as u

Expand Down Expand Up @@ -91,7 +96,10 @@ def r(self, count):
self.sendcmd('FORM:DATA REAL,64')
self.sendcmd(msg)
data = self.binblockread(8, fmt=">d")
return data * units
if numpy:
return data * units
else:
return tuple(val * units for val in data)

# DATA READING METHODS #

Expand All @@ -110,7 +118,10 @@ def fetch(self):
:rtype: `list` of `~pint.Quantity` elements
"""
units = UNITS[self.mode]
return list(map(float, self.query('FETC?').split(','))) * units
data = list(map(float, self.query('FETC?').split(',')))
if numpy:
return data * units
return tuple(val * units for val in data)

def read_data(self, sample_count):
"""
Expand All @@ -133,7 +144,10 @@ def read_data(self, sample_count):
units = UNITS[self.mode]
self.sendcmd('FORM:DATA ASC')
data = self.query('DATA:REM? {}'.format(sample_count)).split(',')
return list(map(float, data)) * units
data = list(map(float, data))
if numpy:
return data * units
return tuple(val * units for val in data)

def read_data_nvmem(self):
"""
Expand All @@ -143,7 +157,9 @@ def read_data_nvmem(self):
"""
units = UNITS[self.mode]
data = list(map(float, self.query('DATA:DATA? NVMEM').split(',')))
return data * units
if numpy:
return data * units
return tuple(val * units for val in data)

def read_last_data(self):
"""
Expand Down
12 changes: 6 additions & 6 deletions instruments/hp/hp6624a.py
Expand Up @@ -250,9 +250,9 @@ def voltage(self):
of units Volts.
:type: `list` of `~pint.Quantity` with units Volt
"""
return [
return tuple([
self.channel[i].voltage for i in range(self.channel_count)
]
])

@voltage.setter
def voltage(self, newval):
Expand All @@ -276,9 +276,9 @@ def current(self):
of units Amps.
:type: `list` of `~pint.Quantity` with units Amp
"""
return [
return tuple([
self.channel[i].current for i in range(self.channel_count)
]
])

@current.setter
def current(self, newval):
Expand All @@ -301,7 +301,7 @@ def voltage_sense(self):
:units: :math:`\\text{V}` (volts)
:rtype: `tuple` of `~pint.Quantity`
"""
return (
return tuple(
self.channel[i].voltage_sense for i in range(self.channel_count)
)

Expand All @@ -313,7 +313,7 @@ def current_sense(self):
:units: :math:`\\text{A}` (amps)
:rtype: `tuple` of `~pint.Quantity`
"""
return (
return tuple(
self.channel[i].current_sense for i in range(self.channel_count)
)

Expand Down
13 changes: 11 additions & 2 deletions instruments/keithley/keithley2182.py
Expand Up @@ -7,10 +7,15 @@
# IMPORTS #####################################################################

from enum import Enum
from instruments.units import ureg as u

try:
import numpy
except ImportError:
numpy = None

from instruments.generic_scpi import SCPIMultimeter
from instruments.abstract_instruments import Multimeter
from instruments.units import ureg as u
from instruments.util_fns import ProxyList

# CLASSES #####################################################################
Expand Down Expand Up @@ -214,7 +219,11 @@ def fetch(self):
:return: Measurement readings from the instrument output buffer.
:rtype: `list` of `~pint.Quantity` elements
"""
return list(map(float, self.query("FETC?").split(","))) * self.units
data = list(map(float, self.query("FETC?").split(",")))
unit = self.units
if numpy:
return data * unit
return tuple(d * unit for d in data)

def measure(self, mode=None):
"""
Expand Down
17 changes: 11 additions & 6 deletions instruments/srs/srs830.py
Expand Up @@ -12,7 +12,10 @@
import warnings
from enum import Enum, IntEnum

import numpy as np
try:
import numpy
except ImportError:
numpy = None

from instruments.abstract_instruments.comm import (
GPIBCommunicator,
Expand Down Expand Up @@ -380,7 +383,9 @@ def take_measurement(self, sample_rate, num_samples):
ch1 = self.read_data_buffer('ch1')
ch2 = self.read_data_buffer('ch2')

return np.array([ch1, ch2])
if numpy:
return numpy.array([ch1, ch2])
return ch1, ch2

# OTHER METHODS #

Expand Down Expand Up @@ -517,10 +522,10 @@ def read_data_buffer(self, channel):
# Query device for entire buffer, returning in ASCII, then
# converting to a list of floats before returning to the
# calling method
return np.fromstring(
self.query('TRCA?{},0,{}'.format(channel, N)).strip(),
sep=','
)
data = self.query('TRCA?{},0,{}'.format(channel, N)).strip()
if numpy:
return numpy.fromstring(data, sep=',')
return tuple(map(float, data.split(",")))

def clear_data_buffer(self):
"""
Expand Down
13 changes: 10 additions & 3 deletions instruments/srs/srsctc100.py
Expand Up @@ -9,7 +9,10 @@
from contextlib import contextmanager
from enum import Enum

import numpy as np
try:
import numpy
except ImportError:
numpy = None

from instruments.generic_scpi import SCPIInstrument
from instruments.units import ureg as u
Expand Down Expand Up @@ -257,8 +260,12 @@ def get_log(self):

# Make an empty quantity that size for the times and for the channel
# values.
ts = u.Quantity(np.empty((n_points,)), 'ms')
temps = u.Quantity(np.empty((n_points,)), units)
if numpy:
ts = u.Quantity(numpy.empty((n_points,)), u.ms)
temps = u.Quantity(numpy.empty((n_points,)), units)
else:
ts = [u.Quantity(0, u.ms)] * n_points
temps = [u.Quantity(0, units)] * n_points

# Reset the position to the first point, then save it.
# pylint: disable=protected-access
Expand Down
13 changes: 10 additions & 3 deletions instruments/tektronix/tekawg2000.py
Expand Up @@ -8,7 +8,10 @@

from enum import Enum

import numpy as np
try:
import numpy
except ImportError:
numpy = None

from instruments.generic_scpi import SCPIInstrument
from instruments.units import ureg as u
Expand Down Expand Up @@ -231,6 +234,10 @@ def upload_waveform(self, yzero, ymult, xincr, waveform):
that all absolute values contained within the array should not
exceed 1.
"""
if numpy is None:
raise ImportError("Missing optional dependency numpy, which is required"
"for uploading waveforms.")

if not isinstance(yzero, float) and not isinstance(yzero, int):
raise TypeError("yzero must be specified as a float or int")

Expand All @@ -240,10 +247,10 @@ def upload_waveform(self, yzero, ymult, xincr, waveform):
if not isinstance(xincr, float) and not isinstance(xincr, int):
raise TypeError("xincr must be specified as a float or int")

if not isinstance(waveform, np.ndarray):
if not isinstance(waveform, numpy.ndarray):
raise TypeError("waveform must be specified as a numpy array")

if np.max(np.abs(waveform)) > 1:
if numpy.max(numpy.abs(waveform)) > 1:
raise ValueError("The max value for an element in waveform is 1.")

self.sendcmd("WFMP:YZERO {}".format(yzero))
Expand Down
19 changes: 14 additions & 5 deletions instruments/tektronix/tekdpo4104.py
Expand Up @@ -10,7 +10,10 @@
from time import sleep
from enum import Enum

import numpy as np
try:
import numpy
except ImportError:
numpy = None

from instruments.abstract_instruments import (
OscilloscopeChannel,
Expand Down Expand Up @@ -111,7 +114,10 @@ def read_waveform(self, bin_format=True):
sleep(0.02) # Work around issue with 2.48 firmware.
raw = self._tek.query("CURVE?")
raw = raw.split(",") # Break up comma delimited string
raw = np.array(raw, dtype=np.float) # Convert to numpy array
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")
Expand All @@ -127,14 +133,17 @@ def read_waveform(self, bin_format=True):
ymult = self._tek.query("WFMP:YMU?") # Retrieve Y multiplier
yzero = self._tek.query("WFMP:YZE?") # Retrieve Y zero

y = ((raw - yoffs) * float(ymult)) + float(yzero)

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?")

x = np.arange(float(ptcnt)) * float(xincr) + float(xzero)
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))

Expand Down
45 changes: 35 additions & 10 deletions instruments/tektronix/tekdpo70000.py
Expand Up @@ -10,6 +10,11 @@
from enum import Enum
import time

try:
import numpy
except ImportError:
numpy = None

from instruments.abstract_instruments import (
Oscilloscope, OscilloscopeChannel, OscilloscopeDataSource
)
Expand All @@ -22,6 +27,8 @@

# CLASSES #####################################################################

# pylint: disable=too-many-lines


class TekDPO70000(SCPIInstrument, Oscilloscope):

Expand Down Expand Up @@ -148,11 +155,11 @@ def _dtype(binary_format, byte_order, n_bytes):
return "{}{}{}".format({
TekDPO70000.ByteOrder.big_endian: ">",
TekDPO70000.ByteOrder.little_endian: "<"
}[byte_order], {
}[byte_order], (n_bytes if n_bytes is not None else ""), {
TekDPO70000.BinaryFormat.int: "i",
TekDPO70000.BinaryFormat.uint: "u",
TekDPO70000.BinaryFormat.float: "f"
}[binary_format], n_bytes)
}[binary_format])

# CLASSES #

Expand Down Expand Up @@ -186,7 +193,7 @@ def read_waveform(self, bin_format=True):
dtype = self._parent._dtype(
self._parent.outgoing_binary_format,
self._parent.outgoing_byte_order,
n_bytes
n_bytes=None
)
self._parent.sendcmd("CURV?")
raw = self._parent.binblockread(n_bytes, fmt=dtype)
Expand Down Expand Up @@ -478,10 +485,18 @@ class SpectralWindow(Enum):

def _scale_raw_data(self, data):
# TODO: incorperate the unit_string somehow
return self.scale * (
(TekDPO70000.VERT_DIVS / 2) *
data.astype(float) / (2**15) - self.position
if numpy:
return self.scale * (
(TekDPO70000.VERT_DIVS / 2) * data.astype(float) / (2**15) - self.position
)

scale = self.scale
position = self.position
rval = tuple(
scale * ((TekDPO70000.VERT_DIVS / 2) * d / (2 ** 15) - position)
for d in map(float, data)
)
return rval

class Channel(DataSource, OscilloscopeChannel):

Expand Down Expand Up @@ -614,10 +629,20 @@ class Coupling(Enum):
)

def _scale_raw_data(self, data):
return self.scale * (
(TekDPO70000.VERT_DIVS / 2) *
data.astype(float) / (2**15) - self.position
) + self.offset
scale = self.scale
position = self.position
offset = self.offset

if numpy:
return scale * (
(TekDPO70000.VERT_DIVS / 2) *
data.astype(float) / (2**15) - position
) + offset

return tuple(
scale * ((TekDPO70000.VERT_DIVS / 2) * d / (2 ** 15) - position) + offset
for d in map(float, data)
)

# PROPERTIES ##

Expand Down

0 comments on commit 0e77a5f

Please sign in to comment.