From 58571485dbe97b06ad29843ea81cc763ebc8151c Mon Sep 17 00:00:00 2001 From: Jeff Damasco Date: Sun, 9 Sep 2018 09:30:16 -0500 Subject: [PATCH] Updates to documentation, more to come --- labdrivers/oxford/itc503.py | 82 ++++++++++++--------------------- labdrivers/oxford/mercuryips.py | 73 +++++++++++++++++------------ labdrivers/oxford/triton200.py | 33 ++++++------- 3 files changed, 86 insertions(+), 102 deletions(-) diff --git a/labdrivers/oxford/itc503.py b/labdrivers/oxford/itc503.py index df7cfbf..0bc3d9d 100644 --- a/labdrivers/oxford/itc503.py +++ b/labdrivers/oxford/itc503.py @@ -1,24 +1,3 @@ -"""Module containing a class to interface with an Oxford Instruments ITC 503. - -Note: Our (Mason Group) laboratory does not have a working motorized needle - valve, so the gas functions are not totally useful. However, if - it somehow is fixed or if someone not from the group decides to use - this module, then it may be of use. - -This module requires a National Instruments VISA driver, which can be found at -https://www.ni.com/visa/ - -Attributes: - resource_manager: the pyvisa resource manager which provides the visa - objects used for communicating over the GPIB interface - - logger: a python logger object - - -Classes: - itc503: a class for interfacing with a ITC 503 temperature controller - -""" import logging import visa @@ -36,25 +15,23 @@ class Itc503: + """ + Module to connect to an ITC 503. + + Modes supported: GPIB + + :param gpib_addr: GPIB address of the ITC 503 + """ def __init__(self, gpib_addr=24): - """Instantiate an Itc503 object. - - :param gpib_addr: GPIB address of the ITC 503 - """ self._visa_resource = resource_manager.open_resource("GPIB::%d" % gpib_addr) self._visa_resource.read_termination = '\r' def setControl(self, unlocked=1, remote=1): """Set the LOCAL / REMOTE control state of the ITC 503 - 0 - Local & Locked (default state) - 1 - Remote & Locked - 2 - Local & Unlocked - 3 - Remote & Unlocked - - :param unlocked: 0 to lock, 1 to unlock - :param remote: 0 for local, 1 for remote + :param unlocked (int): 0 to lock, 1 to unlock + :param remote (int): 0 for local, 1 for remote :return: None """ state_bit = str(remote) + str(unlocked) @@ -64,11 +41,8 @@ def setControl(self, unlocked=1, remote=1): def setTemperature(self, temperature=0.010): """Change the temperature set point. - - Args: - temperature(float): temperature to move to in Kelvin. - Default: 0.010 K (10 mK) for default no heating - above base temperature for any system. + + :param temperature (float): Temperature set point in Kelvin (default: 0.010) """ assert type(temperature) in [int, float], 'argument must be a number' @@ -77,19 +51,22 @@ def setTemperature(self, temperature=0.010): def getValue(self, variable=0): """Read the variable defined by the index. - - There are values 11-13 but generally useless for - general use. These are omitted. - - 0: SET TEMPERATURE 6: HEATER O/P (as V) - 1: SENSOR 1 TEMPERATURE 7: GAS FLOW O/P (a.u.) - 2: SENSOR 2 TEMPERATURE 8: PROPORTIONAL BAND - 3: SENSOR 3 TEMPERATURE 9: INTEGRAL ACTION TIME - 4: TEMPERATURE ERROR 10: DERIVATIVE ACTION TIME - 5: HEATER O/P (as %) - - Args: - variable: Index of variable to read. + + The possible inputs are:: + + 0: SET TEMPERATURE + 1: SENSOR 1 TEMPERATURE + 2: SENSOR 2 TEMPERATURE + 3: SENSOR 3 TEMPERATURE + 4: TEMPERATURE ERROR + 5: HEATER O/P (as %) + 6: HEATER O/P (as V) + 7: GAS FLOW O/P (a.u.) + 8: PROPORTIONAL BAND + 9: INTEGRAL ACTION TIME + 10: DERIVATIVE ACTION TIME + + :param variable (int): Index of variable to read. """ assert type(variable) == int, 'Argument must be an integer.' assert variable in range(0,11), 'Argument is not a valid number.' @@ -102,9 +79,8 @@ def getValue(self, variable=0): def setProportional(self, prop=0): """Sets the proportional band. - - Args: - prop: Proportional band, in steps of 0.0001K. + + :param prop (float): Proportional band, in steps of 0.0001K. """ self._visa_resource.write('$P{}'.format(prop)) return None diff --git a/labdrivers/oxford/mercuryips.py b/labdrivers/oxford/mercuryips.py index d131cc9..1632db5 100644 --- a/labdrivers/oxford/mercuryips.py +++ b/labdrivers/oxford/mercuryips.py @@ -4,30 +4,37 @@ class MercuryIps: - PORT_NO = 7020 # Magnet class class Magnet: + """ + Constructor for a magnet along a certain axis. + + :param axis: The axis for the magnet, given by ['GRPX'|'GRPY'|'GRPZ'] + :type axis: string + :param mode: Connection, given by ['ip'|'visa'] + :type mode: string + :param resource_name: VISA resource name of the MercuryIPS + :type resource_name: string + :param ip_address: IP address of the MercuryIPS + :type ip_address: string + :param port: Port number of the Mercury iPS + :type port: integer + :param timeout: Time to wait for a response from the MercuryIPS before throwing an error. + :type timeout: float + :param bytes_to_read: Amount of information to read from a response + :type bytes_to_read: integer + """ - def __init__(self, axis, mode='ip', resource_name=None, ip_address=None, timeout=10.0, + def __init__(self, axis, mode='ip', resource_name=None, ip_address=None, port=7020, timeout=10.0, bytes_to_read=2048): - """ - Constructor for a magnet along a certain axis. - - :param axis: The axis for the magnet, given by ['GRPX'|'GRPY'|'GRPZ'] - :param mode: Connection, given by ['ip'|'visa'] - :param resource_name: VISA resource name of the MercuryIPS - :param ip_address: IP address of the MercuryIPS - :param timeout: Time to wait for a response from the MercuryIPS before throwing an error. - :param bytes_to_read: Amount of information to read from a response - """ self.axis = axis - self.mode = mode self.resource_name = resource_name self.resource_manager = visa.ResourceManager() self.ip_address = ip_address + self.port = port self.timeout = timeout self.bytes_to_read = bytes_to_read @@ -39,10 +46,11 @@ def query_ip(self, command): """Sends a query to the MercuryIPS via ethernet. :param command: The command, which should be in the NOUN + VERB format - :return: The MercuryIPS response + :type command: string + :returns str: The MercuryIPS response """ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.connect((self.ip_address, MercuryIps.PORT_NO)) + s.connect((self.ip_address, self.port)) s.settimeout(self.timeout) s.sendall(command.encode()) response = s.recv(self.bytes_to_read).decode() @@ -53,7 +61,8 @@ def query_visa(self, command): """Sends a query to the MercuryIPS via VISA. :param command: The command, which should be in the NOUN + VERB format - :return: The MercuryIPS response + :type command: string + :returns str: The MercuryIPS response """ instr = self.resource_manager.open_resource(self.resource_name) response = instr.query(command) @@ -66,9 +75,10 @@ def extract_value(response, noun, unit): """Finds the value that is contained within the response to a previously sent query. :param response: The response from a query. + :type response: string :param noun: The part of the query that refers to the NOUN (refer to MercuryIPS documentation). :param unit: The measurement unit (e.g. K for Kelvin, T for Tesla). - :return: A floating-point value of the response, but without units. + :returns float: The value of the response, but without units. """ expected_response = 'STAT:' + noun + ':' value = float(response.replace(expected_response, '').strip('\n').replace(unit, '')) @@ -79,7 +89,7 @@ def extract_value(response, noun, unit): @property def field_setpoint(self): - """The magnetic field setpoint in Tesla along the magnet axis.""" + """The magnetic field set point in Tesla""" noun = 'DEV:' + self.axis + ':PSU:SIG:FSET' command = 'READ:' + noun + '\n' response = MercuryIps.Magnet.QUERY_AND_RECEIVE[self.mode](self, command) @@ -117,7 +127,7 @@ def field_ramp_rate(self, value): @property def current_setpoint(self): - """The setpoint of the current for a magnet in Amperes.""" + """The set point of the current for a magnet in Amperes.""" noun = 'DEV:' + self.axis + ':PSU:SIG:CSET' command = 'READ:' + noun + '\n' response = MercuryIps.Magnet.QUERY_AND_RECEIVE[self.mode](self, command) @@ -151,6 +161,7 @@ def current_ramp_rate(self, value): @property def magnetic_field(self): + """Gets the magnetic field.""" noun = 'DEV:' + self.axis + ':PSU:SIG:FLD' command = 'READ:' + noun + '\n' response = MercuryIps.Magnet.QUERY_AND_RECEIVE[self.mode](self, command) @@ -218,14 +229,18 @@ def clamped(self): def __init__(self, mode='ip', resource_name=None, - ip_address=None, timeout=10.0, bytes_to_read=2048): + ip_address=None, port=7020, timeout=10.0, bytes_to_read=2048): """ Parameters: - :param mode: ['ip'|'visa'] - :param resource_name: VISA resource name of the Mercury iPS - :param ip_address: IP address of the Mercury iPS + :param str mode: The connection to the iPS, either 'ip' or 'visa' + :param str resource_name: VISA resource name of the Mercury iPS + :param str ip_address: IP address of the Mercury iPS + :param port: Port number of the Mercury iPS + :type port: integer :param timeout: Time in seconds to wait for command acknowledgment + :type timeout: float :param bytes_to_read: Number of bytes to read from query + :type bytes_to_read: integer """ supported_modes = ('ip', 'visa') @@ -234,12 +249,12 @@ def __init__(self, mode='ip', else: raise RuntimeError('Mode is not currently supported.') - self.x_magnet = MercuryIps.Magnet('GRPX', mode=mode, resource_name=resource_name, - ip_address=ip_address, timeout=timeout, bytes_to_read=bytes_to_read) - self.y_magnet = MercuryIps.Magnet('GRPY', mode=mode, resource_name=resource_name, - ip_address=ip_address, timeout=timeout, bytes_to_read=bytes_to_read) - self.z_magnet = MercuryIps.Magnet('GRPZ', mode=mode, resource_name=resource_name, - ip_address=ip_address, timeout=timeout, bytes_to_read=bytes_to_read) + self.x_magnet = MercuryIps.Magnet('GRPX', mode=mode, resource_name=resource_name, ip_address=ip_address, + port=7020, timeout=timeout, bytes_to_read=bytes_to_read) + self.y_magnet = MercuryIps.Magnet('GRPY', mode=mode, resource_name=resource_name, ip_address=ip_address, + port=7020, timeout=timeout, bytes_to_read=bytes_to_read) + self.z_magnet = MercuryIps.Magnet('GRPZ', mode=mode, resource_name=resource_name, ip_address=ip_address, + port=7020, timeout=timeout, bytes_to_read=bytes_to_read) def circle_sweep(self, field_radius, number_points): pass diff --git a/labdrivers/oxford/triton200.py b/labdrivers/oxford/triton200.py index f387dd1..3c8fe14 100644 --- a/labdrivers/oxford/triton200.py +++ b/labdrivers/oxford/triton200.py @@ -2,25 +2,19 @@ class Triton200: + """ + Create an instance of the Triton200 class. - RUO2_CHANNEL = '5' - CERNOX_CHANNEL = '6' + Supported modes: IP - VALID_CHANNELS = (CERNOX_CHANNEL, RUO2_CHANNEL) - - HEATER_RANGE = ['0.316', '1', '3.16', '10', '31.6', '100'] + :param str ip_address: The IP address of the Triton 200. + :param int port_number: The associated port number of the Triton 200 (default: 33576) + :param int timeout: How long to wait for a response (default: 10000) + :param int bytes_to_read: How many bytes to accept from the response (default: 2048) + """ def __init__(self, ip_address, port_number=33576, timeout=10000, bytes_to_read=2048): - """ - Constructor for the Triton200 class. - - :param ip_address: The IP address of the Triton 200. - :param port_number: The associated port number of the Triton 200. - (default: 33576, as per the Triton 200 manual) - :param timeout: How long to wait for a response. (default: 10000) - :param bytes_to_read: How many bytes to accept from the response. - (defualt: 2048) - """ + self._address = (str(ip_address), int(port_number)) self._timeout = timeout self._bytes_to_read = bytes_to_read @@ -34,7 +28,7 @@ def __init__(self, ip_address, port_number=33576, timeout=10000, bytes_to_read=2 @property def temperature_channel(self): """ - :return: The temperature channel, either the cernox (5) or the RuO2 (6) + :returns str: The temperature channel, either the cernox (5) or the RuO2 (6) """ return self._temperature_channel @@ -58,9 +52,7 @@ def temperature_setpoint(self, value): @property def temperature(self): - """ - :return: The temperature reading from the current temperature channel. - """ + """The temperature reading from the current temperature channel.""" noun = 'DEV:T' + str(self.temperature_channel) + ':TEMP:SIG:TEMP' command = 'READ:' + noun + '\r\n' response = self.query_and_receive(command) @@ -72,6 +64,7 @@ def update_heater(self): Associates the heater with the current temperature channel and changes the heater current to preset values given the temperature set point. """ + heater_range = ['0.316', '1', '3.16', '10', '31.6', '100'] command = 'SET:DEV:T' + str(self.temperature_channel) + ':TEMP:LOOP:HTR:H' + str(self._heater_channel) + '\r\n' response = self.query_and_receive(command) @@ -83,7 +76,7 @@ def update_heater(self): + (self.temperature_setpoint > 0.300) + (self.temperature_setpoint > 1.000) + (self.temperature_setpoint > 1.500)) - heater_current = Triton200.HEATER_RANGE[heater_index] + heater_current = heater_range[heater_index] command = 'SET:DEV:T' + str(self.temperature_channel) + ':TEMP:LOOP:RANGE:' + heater_current + '\r\n' response = self.query_and_receive(command)