devctrl.devices.lock_in.impl.sr830.SR830#
- class SR830(instr, check_front_switch=True)[source]#
Bases:
LockInAmpWrapper class for the SR830 controlled via pyvisa
Methods
Manually add a specific device.
Retrieve data from the buffer
DEPRECATED Get the data from the buffer.
Get the maximum buffer size for storing samples
Query the number of points in the buffer :return:
Check if the target number of points are in the buffer
Configure buffer settings for data acquisition
Prepare the device for a buffer (curve) measurement
Start a buffer measurement that was previously configured with
buffer_setup()Stop the current buffer measurement
Check if bits 0,1,2 in the LIA status register are set.
This function should be overridden by device implementations only, and is not intended to be used directly.
Connect an instance of the device's dummy implementation
Decreases the full-scale sensitivity (output signal range) :return: The new full-scale sensitivity
Decreases the time constant :return: The new time constant
Return a flat dictionary of all base classes below this class :param recurse: If True, recursively search for base classes :return: dict of {class name: class}
Get the highest valid sample rate not exceeding the target
Query the status of the device and return a string describing errors.
Calculate wait time to reach 99% of final value
Increases the full-scale sensitivity (output signal range) :return: The new full-scale sensitivity
Increases the time constant :return: The new time constant
Query whether the device is (still) connected
Get a list of all devices for this type.
Get the wait time required to reach 99% of the final value
Read a single value from the lock-in amplifier
Run SCPI code on the device by writing it
Run a command and check for errors
Acquire a snapshot of multiple instrument values
Clear the LIA status byte by reading it
Try to get into a normal state by flushing the output queue and reading the instrument status
Attributes
- ADC = ['Aux In 1', 'Aux In 2', 'Aux In 3', 'Aux In 4']#
- BUFFER_MAX_LENGTH = 16383#
- CH1 = ['X', 'R', 'X Noise', 'Aux In 1', 'Aux In 2']#
- CH2 = ['Y', 'theta', 'Y Noise', 'Aux In 3', 'Aux In 4']#
- OFLT = [1e-05, 3e-05, 0.0001, 0.0003, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100, 300, 1000.0, 3000.0, 10000.0, 30000.0]#
- OUTP = ['X', 'Y', 'R', 'theta']#
- SRAT = [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]#
- VALID_FILTER_SLOPE = [6, 12, 18, 24]#
- VALID_REFERENCE = ['External', 'Internal']#
- VALID_REFERENCE_TRIGGER = ['Sine', 'Rising Edge', 'Falling Edge']#
- VALID_RESERVE = ['High Reserve', 'Normal', 'Low Noise']#
- VALID_SENSITIVITY_VOLT = [2e-09, 5e-09, 1e-08, 2e-08, 5e-08, 1e-07, 2e-07, 5e-07, 1e-06, 2e-06, 5e-06, 1e-05, 2e-05, 5e-05, 0.0001, 0.0002, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1]#
- VALID_SYNC_FILTER = [0, 1]#
- _CLASS_TYPE = 'implementation'#
- __abstractmethods__ = frozenset({})#
- __annotations__ = {'_manual_devices': list[str]}#
- __dict__ = mappingproxy({'__module__': 'devctrl.devices.lock_in.impl.sr830', '__firstlineno__': 14, '__doc__': '\nWrapper class for the SR830 controlled via pyvisa\n', '_CLASS_TYPE': 'implementation', '__init__': <function SR830.__init__>, '__del__': <function SR830.__del__>, 'run': <function SR830.run>, 'run_and_check': <function SR830.run_and_check>, 'query': <function SR830.query>, 'try_recover_from_communication_error': <function SR830.try_recover_from_communication_error>, 'reset': <function SR830.reset>, 'is_connected': <function SR830.is_connected>, 'OUTP': ['X', 'Y', 'R', 'theta'], 'ADC': ['Aux In 1', 'Aux In 2', 'Aux In 3', 'Aux In 4'], 'read_value': <function SR830.read_value>, 'snap': <function SR830.snap>, 'VALID_REFERENCE': ['External', 'Internal'], 'set_reference': <function SR830.set_reference>, 'set_frequency_Hz': <function SR830.set_frequency_Hz>, 'get_frequency_Hz': <function SR830.get_frequency_Hz>, 'VALID_REFERENCE_TRIGGER': ['Sine', 'Rising Edge', 'Falling Edge'], 'set_reference_trigger': <function SR830.set_reference_trigger>, 'get_reference_trigger': <function SR830.get_reference_trigger>, 'VALID_SENSITIVITY_VOLT': [2e-09, 5e-09, 1e-08, 2e-08, 5e-08, 1e-07, 2e-07, 5e-07, 1e-06, 2e-06, 5e-06, 1e-05, 2e-05, 5e-05, 0.0001, 0.0002, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1], 'set_sensitivity_volt': <function SR830.set_sensitivity_volt>, 'get_sensitivity_volt': <function SR830.get_sensitivity_volt>, 'increase_full_scale_sensitivity_volt': <function SR830.increase_full_scale_sensitivity_volt>, 'decrease_full_scale_sensitivity_volt': <function SR830.decrease_full_scale_sensitivity_volt>, 'OFLT': [1e-05, 3e-05, 0.0001, 0.0003, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100, 300, 1000.0, 3000.0, 10000.0, 30000.0], 'set_time_constant_s': <function SR830.set_time_constant_s>, 'get_time_constant_s': <function SR830.get_time_constant_s>, 'increase_time_constant_s': <function SR830.increase_time_constant_s>, 'decrease_time_constant_s': <function SR830.decrease_time_constant_s>, 'VALID_FILTER_SLOPE': [6, 12, 18, 24], 'set_filter_slope': <function SR830.set_filter_slope>, 'get_filter_slope': <function SR830.get_filter_slope>, 'VALID_SYNC_FILTER': [0, 1], 'set_sync_filter': <function SR830.set_sync_filter>, 'get_sync_filter': <function SR830.get_sync_filter>, 'VALID_RESERVE': ['High Reserve', 'Normal', 'Low Noise'], 'set_reserve': <function SR830.set_reserve>, 'get_reserve': <function SR830.get_reserve>, 'start_check_overloads': <function SR830.start_check_overloads>, 'check_overloads': <function SR830.check_overloads>, 'BUFFER_MAX_LENGTH': 16383, 'buffer_get_max_size': <function SR830.buffer_get_max_size>, 'SRAT': [0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512], 'get_next_valid_sample_rate_Hz': <function SR830.get_next_valid_sample_rate_Hz>, 'CH1': ['X', 'R', 'X Noise', 'Aux In 1', 'Aux In 2'], 'CH2': ['Y', 'theta', 'Y Noise', 'Aux In 3', 'Aux In 4'], 'buffer_setup': <function SR830.buffer_setup>, 'buffer_setup_2': <function SR830.buffer_setup_2>, 'buffer_start_fill': <function SR830.buffer_start_fill>, 'buffer_stop_fill': <function SR830.buffer_stop_fill>, 'buffer_is_done': <function SR830.buffer_is_done>, 'buffer_get_n_points': <function SR830.buffer_get_n_points>, 'buffer_get_data': <function SR830.buffer_get_data>, 'buffer_get_data_2': <function SR830.buffer_get_data_2>, '_buffer_get_data_slow': <function SR830._buffer_get_data_slow>, '_buffer_get_data': <function SR830._buffer_get_data>, 'auto_gain': <function SR830.auto_gain>, '_enumerate_devices': <classmethod(<function SR830._enumerate_devices>)>, 'connect_device': <classmethod(<function SR830.connect_device>)>, '__repr__': <function SR830.__repr__>, '__static_attributes__': ('_buffer_ch1', '_buffer_ch2', '_buffer_length', '_buffer_what', 'instr'), '__abstractmethods__': frozenset(), '_abc_impl': <_abc._abc_data object>, '_children': {}, '_manual_devices': []})#
- __firstlineno__ = 14#
- __module__ = 'devctrl.devices.lock_in.impl.sr830'#
- __repr__()[source]#
- Returns:
The name of the device. If applicable, this should include serial port, GPIB address, etc.
- __slots__ = ()#
- __static_attributes__ = ('_buffer_ch1', '_buffer_ch2', '_buffer_length', '_buffer_what', 'instr')#
- __weakref__#
list of weak references to the object
- _abc_impl = <_abc._abc_data object>#
- _buffer_get_data(CH=1, start=0, n_points=None)[source]#
Get the buffer contents in multiple chunks to prevent a timeout when querying many values :param CH: Buffer channel 1 or 2 :param start: start index :param n_points: number of points to take from <start> on :return: numpy.ndarray(n_points-start)
- _buffer_get_data_slow(CH=1, start=0, n_points=None)[source]#
Get the buffer contents by asking for all points and then reading the bytes raw :param CH: Buffer channel 1 or 2 :param start: start index :param n_points: number of points to take from <start> on :return: numpy.ndarray(n_points-start)
- _children = {}#
- _dummies_only = False#
- classmethod _enumerate_devices(query='(GPIB)?*:INSTR')[source]#
This function should be overridden by device implementations only, and is not intended to be used directly. Instead, use list_devices() to get a list of devices. Use enumerate_devices only directly when you only want to list devices of one specific implementation, i.e., only SR830 Lock-In: SR830._enumerate_devices() :param class_name: The name of the device class
- _manual_devices: list[str] = []#
- classmethod add_device(connect_info)#
Manually add a specific device. The device will show up when list_devices() is called for the device type. Call this from the device class implementation, e.g. use ModelXYZ9000.add_device(‘GPIB:1234:5678’) to add a specific device with a fixed GPIB address. This is useful when automatic discovery is undesired/impossible, either because it is not implemented or it disturbs other devices which can’t handle a identification request. :param cls: The device implementation class :param connect_info: A string argument that is passed to the connect() method of the device implementation, when the device is being connected.
- static allow_only_dummy_devices()#
- buffer_get_data(start=0, n_points: int | None = None)[source]#
Retrieve data from the buffer
- Parameters:
start – Starting index for data retrieval
n_points – Number of points to retrieve. None for all available points
- Returns:
NumPy array of shape [Q, N] where Q is number of quantities (same order as configured in ``what```parameter in
buffer_setup()and N is number of points
- buffer_get_data_2(CH1=True, CH2=True, start=0, n_points: int | None = None)[source]#
DEPRECATED Get the data from the buffer. :return: np.ndarray | tuple[np.ndarray, np.ndarray]
- buffer_get_max_size(n_values: int) int[source]#
Get the maximum buffer size for storing samples
- Parameters:
n_values – Number of values stored per sample
- Returns:
Maximum number of samples the buffer can hold
- buffer_setup(what=['R', 'theta'], length=None, sample_rate_Hz=512)[source]#
Configure buffer settings for data acquisition
- Parameters:
what – List of quantities to measure (e.g., [‘R’, ‘theta’])
length – Number of samples to acquire.
sample_rate_Hz – Sample rate in Hz
- buffer_setup_2(CH1='R', CH2='theta', length=None, sample_rate_Hz=512)[source]#
Prepare the device for a buffer (curve) measurement
- Parameters:
CH1 – Source of channel 1: X, R, X Noise, Aux In 1, Aux In 2 or None to use the current source
CH2 – Source of channel 2: Y, theta, Y Noise, Aux In 3, Aux In 4 or None to use the current source
length – Number of values to store in the buffer, or None to use the maximum number of values
sample_rate_Hz – Sample rate in Hz or “Trigger”, see SR830 Manual
- buffer_start_fill()[source]#
Start a buffer measurement that was previously configured with
buffer_setup()
- check_overloads() str[source]#
Check if bits 0,1,2 in the LIA status register are set.
You should clear the register using “start_check_overloads()” when your measurement starts. :return: String describing which kind of overload occurred, or empty string if none occured
- classmethod connect(device_type_name: str, device_name: str | None, **kwargs) Device#
- Parameters:
device_type_name – The name of the device class
device_name – The name of the device class
- classmethod connect_device(device_name)[source]#
This function should be overridden by device implementations only, and is not intended to be used directly. Instead, use list_devices() to get a list of devices, and pass the selected device type and name to connect() :param device_name: The name of the device class
- classmethod connect_dummy(**kwargs) Device#
Connect an instance of the device’s dummy implementation
- decrease_full_scale_sensitivity_volt() float[source]#
Decreases the full-scale sensitivity (output signal range) :return: The new full-scale sensitivity
- decrease_time_constant_s() float[source]#
Decreases the time constant :return: The new time constant
- classmethod get_base_classes(recurse=True) dict[str, type[Device]]#
Return a flat dictionary of all base classes below this class :param recurse: If True, recursively search for base classes :return: dict of {class name: class}
- classmethod get_device_name() str#
- Returns:
The specific type name of the device, e.g., SR830 or Keithly2600
- classmethod get_device_type_name() str#
- Returns:
The general type name of the device, e.g., Lock-In Amplifier or Voltmeter
- get_next_valid_sample_rate_Hz(target_sample_rate_Hz: int | float) int | float[source]#
Get the highest valid sample rate not exceeding the target
- Parameters:
target_sample_rate_Hz – Desired sample rate in Hz
- Returns:
The highest valid sample rate ≤ target_sample_rate_Hz
- get_status() str#
Query the status of the device and return a string describing errors. If everything is ok, empty string must be returned :return: String of device status
- classmethod get_wait_time_s(time_const: float, filter_slope: int)#
Calculate wait time to reach 99% of final value
This method implements the SR830 filter slope timing rules. Subclasses with different filter slopes must override this method.
- Parameters:
time_const – Time constant in seconds
filter_slope – Filter slope in dB/octave (6, 12, 18, or 24)
- Returns:
Wait time in seconds
- Raises:
ValueError – If filter_slope is invalid
- increase_full_scale_sensitivity_volt() float[source]#
Increases the full-scale sensitivity (output signal range) :return: The new full-scale sensitivity
- increase_time_constant_s() float[source]#
Increases the time constant :return: The new time constant
- classmethod list_devices() list[tuple[str, str]]#
Get a list of all devices for this type. The list made up of: - Manually added devices - Available devices (those returned by _enumerate_devices) - A dummy device (if a dummy implementation exists) - List of all devices of child classes
- Returns:
list of available devices
- read_get_wait_time_s(time_const: float | None = None, filter_slope: int | None = None)#
Get the wait time required to reach 99% of the final value
Uses the rule of thumb from SR830 manual to wait 5 time constants (page 6-35) depending on the filter slope. See SR830 Manual 3-21.
- Parameters:
time_const – Time constant in seconds. If None, read from device
filter_slope – Filter slope in dB/octave. If None, read from device
- Returns:
Wait time in seconds to reach 99% of final value
- read_value(which: str, dont_log=True)[source]#
Read a single value from the lock-in amplifier
- Parameters:
which – Which value to read. Must be one of ‘X’, ‘Y’, ‘R’, ‘theta’
- Returns:
The requested value
- run(code, split=True)[source]#
Run SCPI code on the device by writing it
Empty lines, leading whitespaces and lines starting with ‘ or # are ignored.
- Parameters:
code – SCPI commands to execute
split – If True, split commands by newline and execute separately
- run_and_check(cmd)[source]#
Run a command and check for errors
Executes a command on the device and checks the standard event status byte for execution errors or illegal commands. Raises RuntimeError if errors are detected.
- Parameters:
cmd – SCPI command to execute
- Raises:
RuntimeError – If execution error or illegal command detected
pyvisa.VisaIOError – If VISA communication fails
- snap(what='3,4,5,7')[source]#
Acquire a snapshot of multiple instrument values
Takes a single measurement of the specified quantities and returns them as a list.
1 X
2 Y
3 R
4 θ
5 Aux In 1
6 Aux In 2
7 Aux In 3
8 Aux In 4
9 Reference Frequency
10 CH1 display
11 CH2 display
- Parameters:
what – Comma-separated list of value indices to measure (1-11). Default: “3,4,5,7”
- Returns:
List of measured values in the order requested