PyFex
A Rust/Python experiment manager

Introduction
Installation
Instruments
Test_daq
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[device.Test_DAQ]
# Test_DAQ measurement configuration
# Step size in nm
gate_time = 0.1
# Start wavelength (nm)
averages = 500
# Sends mock time series data if set to True
trace = False
Methods
setup_config
measure
Keithley2400
Methods
configure_device
measure
close
SiglentSDS2352XE
Class to create user-fiendly interface with the SiglentSDS2352X-E scope. note! cursors must be on for this method to work!
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[device.SIGLENT_Scope]
# SIGLENT_Scope measurement configuration
# Valid grating name to be used for the measurement, options: VIS, NIR, MIR
acquisition_mode = "AVERAGE"
# Number of averages to collect: 4, 16, 32, 64, 128, 256, 512, 1024
averages = 64
# Enable/Disable rolling averaging
reset_per = True
# Frequency of the trigger source to aproximate waiting x number off averages. The scope doesnt have a query to see if the number of averages has been reached
frquency = 5
# Desired measurement channel
channel = "c1"
# Return the area, or the full trace. Options: area, trace
data_type = "area"
Methods
setup_config
Setup function for the oscilliscope
measure
High level measurement API, calls into measure_sample or measure_trace depending on device configuration.
close
Releases the device.
get_waveform
Signature: get_waveform(channel)
Mostly vendor provided function to return the waveform from the oscilisope.
measure_sample
Returns a single value (voltage) based on the area under the transient. Makes assumption that data is either all negative voltages, or that the signal voltage is more positive than the baseline voltage. In the case the baseline voltage is positive and the signal voltage is more negative, your results may appear inverted. Standard practice is to ensure your baseline voltage and signal voltage is either all positive or all negative for this to work reliably.
Args: Self Returns: float64
measure_trace
Returns the entire trace/waveform from the osciliscope, where t=0 is defined by the x1 cursor. Args: Self Returns: tuple (time: NDarray f64, voltage: NDarray f64)
Scryostation
A class to manage and control a cryostation system, including its configuration, initialization, and operational states such as bake-out, purging, and cooldown.
Attributes
name (str)
Name of the cryostation.
config (dict)
Parsed configuration data for the cryostation.
ip (str)
IP address of the cryostation device.
cryostat (object)
Instance of the cryostation control object.
sock (socket)
TCP socket for communication with the cryostation.
data (dict)
Stores measured data such as temperature, stability, and pressure.
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[instruments.scryostation]
# Scryostation configuration
# Valid IP address of the cryostation or device name (DHCP)
ip_address = "0.0.0.0"
# Initial target temperature for the cryostation in Kelvin
inital_cooldown_target = 5
# Desired temperature stability in Kelvin
desired_stability = 0.1
# Toggle if there will be a bakeout process before cooling the cryostat
enable_bakeout = True
# Bakeout temperature in Kelvin (max 350)
bakeout_temperature = 325
# Time in minutes for the bakeout process
bakeout_time = 30
# Toggle if there will be a nitrogen purge process before cooling the cryostat
enable_purge = True
# Number of nitrogen purges
purges = 5
# Determines what is the primary temperature probe options: 'sample' 'platform'
temperature_probe = "sample"
Methods
setup_config
Signature: setup_config(immediate_start)
Sets up the cryostation configuration and optionally starts the cooldown process.
Args: immediate_start (bool): Whether to immediately start the cryostation cooldown process.
prepare_cryostat
Prepares the cryostation by performing a bake-out, purge, and cooldown in sequence.
bake_out
Configures and initiates the bake-out process for the cryostation.
Retrieves the necessary settings from the configuration and applies them.
purge
Configures and initiates the nitrogen purge process for the cryostation.
Retrieves the necessary settings from the configuration and applies them.
cooldown
Starts the cooldown process for the cryostation.
Raises: RuntimeError: If the system fails to enter the 'Cooldown' state.
warm_up
Initiates the warm-up process for the cryostation.
is_at_setpoint
Signature: is_at_setpoint(tolerance)
Checks if the cryostation has reached its target temperature and stability.
Validates if the cryostation is both within a setpoint tolerance as well as temperature stability.
Args:
tolerance (optional float): Acceptable tolerance between actual and desired setpoint temperature. If unset, it checks if the temperatrue has reached stability and setpoint per the manufacturer.
Returns:
bool: True if the cryostation is at the target setpoint, False otherwise.
go_to_temperature
Signature: go_to_temperature(temperature, stability)
Sets the cryostation to a specific target temperature and stability.
Args: temperature (float): Target temperature in Kelvin. stability (float, optional): Target stability. Defaults to the configured stability.
toggle_magnetic_field
Signature: toggle_magnetic_field(state)
Toggles the magnet on and off.
Args: state (str): "on" or "off" to toggle the magnetic field on and off.
set_magnetic_field
Signature: set_magnetic_field(strength)
Set the magnetic field to a desired field strength
Args: strength (float): Desired field strength in mT
get_magnetic_field
Signature: get_magnetic_field(tolerance)
Checks the magnetic field by first checking its still operational, it then checks that the measured and calculated field strength are within a given tolerance in Tesla Args: tolerance (float (mT)): Acceptable difference between desired and actual field strengths. Automatically converts to T from mT.
Returns: float: Magnetic field strength in mT
measure
Signature: measure(tolerance)
Measures and retrieves the current temperature, stability, and pressure of the scryostation.
Updates the internal data dictionary with the latest measurements and sends the data payload to the rex TCP server.
Returns: dict: A dictionary containing the latest measurements for use within a Python script.
C8855_counting_unit
Class for controlling the C8855 photon counting unit.
Attributes
gate_time_mapping (dict)
Maps human-readable gate times to corresponding hexadecimal values.
transfer_type_mapping (dict)
Maps transfer types to their respective integer values.
trigger_type_mapping (dict)
Maps trigger modes to their respective integer values.
name (str)
Name identifier for the device.
config (dict)
Configuration settings for the device.
connect_to_rex (bool)
Indicates whether to connect to the rex experiment manager.
sock (socket, optional)
Socket connection for rex, if enabled.
data (dict)
Stores measurement data.
toml_config (dict)
Default configuration template for the device
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[device.C8855_photon_counter]
# C8855_photon_counter measurement configuration
# Transfer type, working and validated transfer type is 'block_transfer' however 'single_transfer' is available.
transfer_type = "block_transfer"
# Number of gates: 2,4,8,16,32,64,128,256,512
number_of_gates = 512
# Gate time to use, e.g. '500us' or '1ms', or '2ms' etc. available gate times: '50us': 0x02,'100us','200us','500us','1ms','2ms','5ms','10ms','20ms','50ms','100ms','200ms','500ms','1s','2s','5s','10s'
gate_time = "500us"
# Type of device triggering to use (external, software)
trigger_type = "external"
# Number of averages to take
averages = 16
# Measurement mode to use, counts only (counts_only), trace only (trace), or both as a tupple (all)
measure_mode = "counts_only"
# DLL path to use for C8855 photon counter
dll_path = "/path/to/dll"
Methods
setup_config
Loads device configuration and initializes the DLL functions.
general_measurement
Performs a single measurement cycle, including resetting, setting up, starting, reading, and stopping.
stop_counting
Signature: stop_counting(handle)
Stops the photon counting process.
Args: handle (ctypes.c_void_p): A handle to the C8855 device.
Returns: bool: True if the counting was successfully stopped, False otherwise.
measure
Conducts multiple measurements based on the configured number of averages.
Returns: float | tuple: Depending on measure_mode, returns either total count, trace data, or both.
open_device
Opens a connection to the device.
Returns: ctypes.c_void_p: Handle to the device.
reset_device
Signature: reset_device(handle)
Resets the device to its default state.
Args: handle (ctypes.c_void_p): Device handle.
Returns: bool: True if successful, False otherwise.
close_device
Signature: close_device(handle)
Closes the connection to the device.
Args: handle (ctypes.c_void_p): Device handle.
Returns: int: Status of the close operation.
setup_device
Signature: setup_device(handle, gate_time, transfer_mode, number_of_gates)
Configures the device with the specified parameters.
Args: handle (ctypes.c_void_p): Device handle. gate_time (ctypes.c_ubyte): Gate time setting. transfer_mode (ctypes.c_ubyte): Transfer mode setting. number_of_gates (ctypes.c_ushort): Number of gates for measurement.
Returns: bool: True if setup was successful, False otherwise.
start_counting
Signature: start_counting(handle, trigger_mode)
Starts the counting process.
Args: handle (ctypes.c_void_p): Device handle. trigger_mode (ctypes.c_ubyte, optional): Trigger mode. Defaults to C8855_EXTERNAL_TRIGGER.
Returns: bool: True if counting started successfully, False otherwise.
read_data
Signature: read_data(handle, data_buffer)
Reads data from the device into the provided buffer.
Args: handle (ctypes.c_void_p): Device handle. data_buffer (Pointer_c_ulong): Buffer to store retrieved data.
Test_spectrometer
A basic mock spectrometer class.
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[device.Test_spectrometer]
# Test_spectrometer measurement configuration
# Step size in nm
step_size = 0.1
# Start wavelength (nm)
initial_wavelength = 500
# Stop wavelength in (nm)
final_wavelength = 600
Methods
setup_config
measure
set_wavelength
Signature: set_wavelength(wavelength)
spectrometer_step
Move the wavelength by one step size increment.
Advances the wavelength by the configured step_size value.
total_steps
Return the total number of steps for the current configuration
HoribaiHR550
A class to control and interface with the Horiba iHR550 Spectrometer via libusb.
This class provides a control interface for the iHR550 spectrometer including wavelength control, grating selection, mirror positioning, and slit width adjustment.
Attributes
VENDOR_ID (int)
USB vendor ID for the device (0xC9B)
PRODUCT_ID (int)
USB product ID for the device (0x101)
LANG_ID_US_ENGLISH (int)
Language ID for US English (0x409)
B_REQUEST_OUT (int)
USB output request type (0x40)
B_REQUEST_IN (int)
USB input request type (0xC0)
BM_REQUEST_TYPE (int)
USB request type (0xB3)
CMD_WAVELENGTH_SET (int)
Command index for setting wavelength (4)
CMD_WAVELENGTH_READ (int)
Command index for reading wavelength (2)
CMD_TURRET_SET (int)
Command index for setting turret (17)
CMD_TURRET_READ (int)
Command index for reading turret (16)
CMD_BUSY (int)
Command index for checking busy status (5)
CMD_INIT (int)
Command index for initialization (0)
CMD_SET_MIRROR (int)
Command index for setting mirror (41)
CMD_READ_MIRROR (int)
Command index for reading mirror (40)
CMD_SET_SLITWIDTH (int)
Command index for setting slit width (33)
CMD_READ_SLITWIDTH (int)
Command index for reading slit width (32)
TURRET_MAPPING (dict)
Maps turret indices to grating names
MIRROR_MAPPING (dict)
Maps mirror indices to names
SLIT_MAPPING (dict)
Maps slit names to their indices
toml_config (dict)
Default configuration template for the device
bypass_homing (bool)
Whether to skip the homing sequence
slit_type (int)
Type of slit mechanism (hardcoded to 7)
hardware_config (dict)
Contains gratings and mirrors configuration
_state (dict)
Current state of device (position, turret, mirrors, slits)
_dev (usb.core.Device)
USB device instance
data (dict)
Measurement data storage
config
Bound configuration as defined by the user
connect_to_rex (bool)
Whether to connect to rex experiment manager
sock
Socket connection when rex is enabled
step_size (float)
Step size for measurements (default 0.1nm)
start_wavelength (float)
Initial start wavelength (default 500nm)
final_wavelength (float)
End wavelength for a measurement (default 600nm)
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[device.iHR550]
# IHR550 measurement configuration
# Valid grating name to be used for the measurement, options: VIS, NIR, MIR
grating = "VIS"
# Step size in nm
step_size = 0.1
# Start wavelength (nm)
initial_wavelength = 500
# Stop wavelength in (nm)
final_wavelength = 600
[device.iHR550.slits]
# Slit configuration settings
# Entrance front slit width in mm
Entrance_Front = 0.5
# Entrance side slit width in mm
Entrance_Side = 0.0
# Exit front slit width in mm
Exit_Front = 0.5
# Exit side slit width in mm
Exit_Side = 0.0
[device.iHR550.mirrors]
# Mirror configuration settings
# Orientation of extrance mirror
Entrance = "front"
# Orientation of exit mirror
Exit = "side"
Methods
close
Release the USB device and free associated resources.
Should be called when finished using the device to ensure proper cleanup.
is_busy
Check if the spectrometer is currently busy.
Returns: bool: True if the device is busy, False otherwise
Raises: Exception: If there's an error reading the busy state
wait_until_not_busy
Signature: wait_until_not_busy(poll_interval, timeout)
Wait until the device reports it is not busy.
Args: poll_interval (float, optional): Time between checks in seconds. Defaults to 0.05 timeout (float, optional): Maximum wait time in seconds. Defaults to 30.0
Raises: TimeoutError: If device remains busy longer than timeout period
update_state
Signature: update_state(timeout)
Update the internal state of the device by reading current settings.
Updates turret position, wavelength, mirror positions, and slit widths.
Args: timeout (float, optional): Maximum time to wait for updates in seconds. Defaults to 30.0
set_wavelength
Signature: set_wavelength(wavelength, timeout)
Set the spectrometer to a specific wavelength.
Args: wavelength (float): Target wavelength in nanometers timeout (float, optional): Maximum time to wait for movement in seconds. Defaults to 30.0
Raises: ValueError: If current turret configuration is invalid
get_wavelength
Get the current wavelength setting.
Returns: float: Current wavelength in nanometers
set_turret
Signature: set_turret(turret, timeout)
Set the grating turret to a specific position.
Args: turret (str): Desired turret position ("VIS", "NIR", or "MIR") timeout (float, optional): Maximum time to wait for movement in seconds. Defaults to 400.0
Raises: ValueError: If specified turret position is invalid
set_slit
Signature: set_slit(port, width, timeout)
Set a specific slit to the desired width.
Args: port (str): Slit identifier (e.g., "Entrance_Front", "Exit_Side") width (float): Desired slit width in millimeters timeout (float, optional): Maximum time to wait for movement in seconds. Defaults to 30.0
get_slit
Signature: get_slit(index, timeout)
Read the width of a specific slit.
Args: index (int): Index of the slit to read timeout (float, optional): Maximum time to wait for reading in seconds. Defaults to 30.0
Returns: float: Slit width in millimeters
get_turret
Signature: get_turret(timeout)
Read the current turret position.
Args: timeout (float, optional): Maximum time to wait for reading in seconds. Defaults to 30.0
Returns: int: Current turret index
initialize
Signature: initialize(timeout)
Initialize and home the spectrometer.
If bypass_homing is False, performs a full initialization sequence.
Args: timeout (float, optional): Maximum time to wait for homing in seconds. Defaults to 90.0
setup_device
Configure the device according to the current configuration.
Sets up step size, turret position, initialization, slit widths, mirror positions, and initial wavelength according to the configuration.
total_steps
Return the total number of steps for the current configuration
spectrometer_step
Move the wavelength by one step size increment.
Advances the wavelength by the configured step_size value.
measure
Take a measurement at the current wavelength.
Returns: Dict: Dictionary containing measurement data with wavelength information
get_mirror
Signature: get_mirror(index, timeout)
Read the current position of a specific mirror.
Args: index (int): Mirror index to read timeout (float, optional): Maximum time to wait for reading in seconds. Defaults to 30.0
Returns: str: Mirror position ("side" or "front")
set_mirror
Signature: set_mirror(port, side, timeout)
Set a specific mirror to the desired position.
Args: port (str): Mirror identifier ("Entrance" or "Exit") side (str): Desired position ("side" or "front") timeout (float, optional): Maximum time to wait for movement in seconds. Defaults to 30.0
Test_cryostat
Methods
setup_config
measure
goto_setpoint
Signature: goto_setpoint(setpoint)
set_magneticfield
Signature: set_magneticfield(strength)
get_cryostate
get_magnetstate
Gl100
A class to control and interface with the PTI tunable dye laser.
Attributes
LOWER_LIMIT (float)
Lowest limit laser can be set to in nm (380.00)
UPPER_LIMIT (float)
Highest limit laser can be set to in nm (750.00)
ZERO (string)
Command used to zero the stepper motor (X0= 15T)
GET_MANUFACTURER (string)
Command used to get the manufacturer information (X-12?)
GET_POSTION (string)
Used to get the current stepper motor position (X-1?)
toml_config (dict)
Default configuration template for the device
data (dict)
Measurement data storage
config
Bound configuration as defined by the user
connect_to_rex (bool)
Whether to connect to rex experiment manager
sock
Socket connection when rex is enabled
step_size (float)
Step size for wavelength measurements.
start_wavelength (float)
Initial start wavelength for a scan
final_wavelength (float)
End wavelength for a measurement scan
grating_factor (float)
Factor related to the diffraction grating used in the system.
name (string)
Name or identifier for the device.
scan_data (dict)
Stores data related to the scan, namely positions and motor steps required, as well as error from desired wavelenght goals.
start_measurement_position (float)
Position of the start wavelength in stepper motor units.
end_measurement_position (float)
Position of the end wavelength in stepper motor units.
min_step_size (float)
Minimum allowable step size for the measurement system. (min 1/grating factor nm)
current_index (int)
The current index position within a scan or measurement sequence.
total_steps_from_zero (int)
Total number of steps the stepper motor has moved from the zero position.
total_steps (int)
Total number of steps required to complete the scan from start to end.
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[device.GL100_Dye_Laser]
# GL100_Dye_Laser measurement configuration
# Step size in nm
step_size = 0.1
# Calibrated wavelength from mechanical dial (nm)
initial_position = 490
# Start wavelength in (nm)
start_position = 500
# End wavelength in (nm)
end_position = 600
# Dye used for the experiment
dye = "C540"
Methods
setup_config
Sets up the device configuration by loading necessary parameters from the config file and checks any hardware limits. Connects to the correct port if the device is found.
check_limits
Checks if the configured positions are within the device's wavelength limits. Raises: DeviceError: If any position is outside the defined LOWER_LIMIT or UPPER_LIMIT.
check_step
Signature: check_step(step_size)
Ensures the step size is not smaller than the minimum allowed step size. Logs a warning if the step size is adjusted.
Args: step_size (float): Desired step size.
move_to_next_position
Moves to the next scan position and returns the corresponding scan data.
Returns: dict or None: Next position data or None if scan is complete.
move
Signature: move(steps)
Moves the stepper motor by the specified number of steps.
Args: steps (int): Number of steps to move.
measure
Performs a measurement at the current scan position.
Returns: dict or None: Measurement data at the current position, or None if the scan is complete.
find_correct_port
Signature: find_correct_port(expected_response, baudrate, timeout)
connect
send_command
Signature: send_command(command)
return_to_zero
Return to the zero position by moving exact negative of total steps. Includes backlash compensation.
move_to_start
Move to start position with backlash compensation. Always approaches from lower wavelength to avoid mechanical backlash.
Returns: float: The actual position reached in nm.
SPCS_mixed_signal_box
A class to control and interact with an SPCS Mixed Signal Switch Box.
Attributes
MATRIX_CHANNEL_MAPPING (dict)
Maps logical channel names to matrix channel letters. e.g., "CH1" maps to "A", "CH2" maps to "B", etc.
POLARITY_CHANNEL_MAPPING (dict)
Maps logical channel names to polarity channel letters. e.g., "CH1" maps to "E", "CH2" maps to "F", etc.
MATRIX_MAPPING (dict)
Converts hexadecimal and string representations to integer values. Supports values from '0' to 'f', mapping to integers 0-15.
REVERSE_MATRIX_MAPPING (dict)
Inverted MATRIX_CHANNEL_MAPPING for reverse lookups.
REVERSE_POLARITY_MAPPING (dict)
Inverted POLARITY_CHANNEL_MAPPING for reverse lookups.
name (str)
Name identifier for the device.
config (dict)
Configuration settings for the device.
connect_to_rex (bool)
Indicates whether to connect to the rex experiment manager.
sock (socket, optional)
Socket connection for rex, if enabled.
data (dict)
Stores measurement data.
toml_config (dict)
Default configuration template for the device
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[device.SPCS_mixed_signal_switch_box]
# SPCS_mixed_signal_switch_box measurement configuration
# Reset the device on initilisation either true or false (bool)
reset = True
[device.SPCS_mixed_signal_switch_box.matrix]
# Matrix configuration settings
# Activiation state for the given channel (str) range: 1-f (hexidecimal)
CH1 = "1"
# Activiation state for the given channel (str) range: 1-f (hexidecimal)
CH2 = "2"
# Activiation state for the given channel (str) range: 1-f (hexidecimal)
CH3 = "4"
# Activiation state for the given channel (str) range: 1-f (hexidecimal)
CH4 = "8"
[device.SPCS_mixed_signal_switch_box.polarity]
# polarity configuration settings
# Polarity switch (str) '0' non-inverted '1' inverted
CH1 = "1"
# Polarity switch (str) '0' non-inverted '1' inverted
CH2 = "0"
# Polarity switch (str) '0' non-inverted '1' inverted
CH3 = "1"
# Polarity switch (str) '0' non-inverted '1' inverted
CH4 = "0"
Methods
find_correct_port
Signature: find_correct_port(expected_response, baudrate, timeout)
Automatically find the correct serial port for the matrix switch box.
Args: expected_response (str): The expected response from the device to identify it. baudrate (int, optional): Serial communication baudrate. Defaults to 115200. timeout (int, optional): Connection timeout in seconds. Defaults to 2.
Returns: str or None: The response from the device if found, None otherwise.
Raises: Logs an error if no matching device is found.
connect
Establish a serial connection to the device using the previously identified port.
Sets up a serial connection with 115200 baudrate and 1-second timeout.
set_channel_matrix
Signature: set_channel_matrix(channel, command)
Set the matrix routing for a specific channel.
Args: channel (str): The matrix channel to configure (A, B, C, or D). command (str): The routing configuration (0-15 or hex 0-f).
set_channel_polarity
Signature: set_channel_polarity(channel, command)
Set the polarity for a specific channel.
Args: channel (str): The polarity channel to configure (E, F, G, or H). command (str): Polarity setting (0 = non-inverted, 1 = inverted).
get_state
Retrieve the current state of all channels.
Returns: dict: A dictionary representing the current state of matrix and polarity settings.
update_state
Signature: update_state(response)
Update the internal state based on the device's response.
Args: response (str): A comma-separated string of channel states.
switch_layout
Print a diagram explaining the switch box channel and polarity mapping.
Provides a visual reference for channel routing and polarity configurations.
setup_config
Set up the initial configuration of the device.
Performs a reset if specified in the configuration and sets initial channel states.
reset
Reset all matrix and polarity channels to their default (0) state.
Iterates through all channels, setting matrix routing to 0 and polarity to non-inverted.
set_initial_state
Configure initial matrix and polarity settings based on the configuration.
Sets matrix routing and polarity for channels as specified in the configuration.
measure
Capture the current state of the device and optionally send data to rex.
Returns: dict: A dictionary of current channel states, with each state in a list.
Ocean_optics_spectrometer
A class to control and interact with an OceanOptics Spectrometer.
Attributes
name (str)
Name identifier for the device.
config (dict)
Configuration settings for the device.
connect_to_rex (bool)
Indicates whether to connect to the rex experiment manager.
sock (socket, optional)
Socket connection for rex, if enabled.
data (dict)
Stores measurement data.
toml_config (dict)
Default configuration template for the device
Configuration
This class requires configuration in your config.toml
file:
Example Configuration
[device.OceanOpitics_Spectrometer]
# OceanOpitics_Spectrometer measurement configuration
# Integration time in microseconds
integration_time = 50000
# Number of averages
averages = 1
# Upper wavelength range
upper_limit = 600
# Lower wavelength range
lower_limit = 500
# which backend to use to connect, options: 'pyseabreeze', 'cseabreeze'
backend = "pyseabreeze"
Methods
setup_config
measure
bounds
Signature: bounds(data, lower_limit, upper_limit)