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)

Information