devctrl.devices.lock_in.impl.model7260.Model7260#

class Model7260(instr, check_front_switch=True)[source]#

Bases: LockInAmp

Wrapper class for the Model 7260 DSP Lock-In controlled via pyvisa

Methods

add_device

Manually add a specific device.

allow_only_dummy_devices

auto_gain

auto_sensitivity

buffer_get_data

Get the data from the buffer.

buffer_get_max_size

Get the maximum buffer size for storing samples

buffer_get_n_points

Query the number of points in the buffer :return:

buffer_is_done

Check if the target number of points are in the buffer

buffer_setup

Compatibility function with same syntax as SR830 :param what: Quantities to measure. The Model7260 can measure more than 2 at a time! :param length: Number of values to measure or None to fill the buffer to the maximum. The max length depends on how many quantities are measured. :param sample_rate: This will be converted to a measurement interval and rounded to 5 ms. So you might not get the exact same sample rate as with the SR830, but you can choose arbitrary values.

buffer_start_fill

Start a buffer measurement that was previously configured with buffer_setup()

buffer_stop_fill

Stop the current buffer measurement

check_overloads

Check the overload status byte

check_status

Check the device status

connect

connect_device

This function should be overridden by device implementations only, and is not intended to be used directly.

connect_dummy

Connect an instance of the device's dummy implementation

decrease_ac_gain_db

decrease_full_scale_sensitivity_volt

Decreases the full-scale sensitivity (output signal range) :return: The new full-scale sensitivity

decrease_time_constant_s

Decreases the time constant :return: The new time constant

get_ac_gain_db

get_base_classes

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_device_name

get_device_type_name

get_filter_slope

get_frequency_Hz

get_next_valid_sample_rate_Hz

Get the highest valid sample rate not exceeding the target

get_reference_trigger

get_reserve

get_sensitivity_volt

get_status

Query the status of the device and return a string describing errors.

get_sync_filter

TODO: Actually is Synchronous time constant control and not a filter

get_time_constant_s

get_wait_time_s

see read_get_wait_time_s

increase_ac_gain_db

increase_full_scale_sensitivity_volt

Increases the full-scale sensitivity (output signal range) :return: The new full-scale sensitivity

increase_time_constant_s

Increases the time constant :return: The new time constant

is_connected

Query whether the device is (still) connected

list_devices

Get a list of all devices for this type.

party

query

read_get_wait_time_s

Get the wait time required to reach 99% of the final value

read_value

Read a single value from the lock-in amplifier

reset

run

Run SCPI code on the device by writing it

run_and_check

Run a command and check for errors

set_ac_gain_db

set_default_display

set_filter_slope

set_frequency_Hz

set_reference

set_reference_trigger

set_reserve

set_sensitivity_volt

set_sync_filter

set_time_constant_s

start_check_overloads

try_recover_from_communication_error

Try to get into a normal state by flushing the output queue and reading the instrument status

Attributes

AC_GAIN = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]#
ADC = ['ADC1', 'ADC2', 'ADC3']#
ADC_SR830 = ['Aux In 1', 'Aux In 2', 'Aux In 3']#
BUFFER_MAX_LENGTH = 32768#
CBD_BITS = ['X', 'Y', 'MAG', 'PHASE', 'SENS', 'ADC1', 'ADC2']#
CBD_BITS_SR830 = ['X', 'Y', 'R', 'theta', 'SENS', 'Aux In 1', 'Aux In 2']#
IE = ['INT', 'EXT LOGIC', 'EXT']#
OVERLOADS = [None, 'CH1 Output', 'CH2 Output', 'Y Channel Output', 'X Channel Output', None, 'Input', 'Reference Unlock']#
READ_CMDS = {'R': 'MAG.', 'X': 'X.', 'Y': 'Y.', 'theta': 'PHA.'}#
REFERENCE_SR830 = {'External': 'EXT LOGIC', 'Internal': 'INT'}#
RSLP = ['Sine', 'Rising Edge', 'Falling Edge']#
SEN = [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]#
SLOPE = [6, 12, 18, 24]#
ST = [None, 'Invalid Command', 'Command parameter error', 'Reference unlock', 'Overload', None, 'Asserted SRQ', None]#
TC = [1e-05, 2e-05, 4e-05, 8e-05, 0.00016, 0.00032, 0.00064, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000.0, 2000.0, 5000.0, 10000.0, 20000.0, 50000.0, 100000.0]#
_CLASS_TYPE = 'implementation'#
__abstractmethods__ = frozenset({})#
__annotations__ = {'_manual_devices': list[str]}#
__del__()[source]#

Properly close the instrument connection

__dict__ = mappingproxy({'__module__': 'devctrl.devices.lock_in.impl.model7260', '__firstlineno__': 12, '__doc__': '\nWrapper class for the Model 7260 DSP Lock-In controlled via pyvisa\n', '_CLASS_TYPE': 'implementation', '__init__': <function Model7260.__init__>, '__del__': <function Model7260.__del__>, 'run': <function Model7260.run>, 'run_and_check': <function Model7260.run_and_check>, 'ST': [None, 'Invalid Command', 'Command parameter error', 'Reference unlock', 'Overload', None, 'Asserted SRQ', None], 'check_status': <function Model7260.check_status>, 'query': <function Model7260.query>, 'try_recover_from_communication_error': <function Model7260.try_recover_from_communication_error>, 'reset': <function Model7260.reset>, 'is_connected': <function Model7260.is_connected>, 'party': <function Model7260.party>, 'set_default_display': <function Model7260.set_default_display>, 'READ_CMDS': {'X': 'X.', 'Y': 'Y.', 'R': 'MAG.', 'theta': 'PHA.'}, 'ADC': ['ADC1', 'ADC2', 'ADC3'], 'ADC_SR830': ['Aux In 1', 'Aux In 2', 'Aux In 3'], 'read_value': <function Model7260.read_value>, 'REFERENCE_SR830': {'Internal': 'INT', 'External': 'EXT LOGIC'}, 'IE': ['INT', 'EXT LOGIC', 'EXT'], 'set_reference': <function Model7260.set_reference>, 'set_frequency_Hz': <function Model7260.set_frequency_Hz>, 'get_frequency_Hz': <function Model7260.get_frequency_Hz>, 'RSLP': ['Sine', 'Rising Edge', 'Falling Edge'], 'set_reference_trigger': <function Model7260.set_reference_trigger>, 'get_reference_trigger': <function Model7260.get_reference_trigger>, 'SEN': [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 Model7260.set_sensitivity_volt>, 'get_sensitivity_volt': <function Model7260.get_sensitivity_volt>, 'increase_full_scale_sensitivity_volt': <function Model7260.increase_full_scale_sensitivity_volt>, 'decrease_full_scale_sensitivity_volt': <function Model7260.decrease_full_scale_sensitivity_volt>, 'TC': [1e-05, 2e-05, 4e-05, 8e-05, 0.00016, 0.00032, 0.00064, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000.0, 2000.0, 5000.0, 10000.0, 20000.0, 50000.0, 100000.0], 'set_time_constant_s': <function Model7260.set_time_constant_s>, 'get_time_constant_s': <function Model7260.get_time_constant_s>, 'increase_time_constant_s': <function Model7260.increase_time_constant_s>, 'decrease_time_constant_s': <function Model7260.decrease_time_constant_s>, 'SLOPE': [6, 12, 18, 24], 'set_filter_slope': <function Model7260.set_filter_slope>, 'get_filter_slope': <function Model7260.get_filter_slope>, 'get_wait_time_s': <staticmethod(<function Model7260.get_wait_time_s>)>, 'set_sync_filter': <function Model7260.set_sync_filter>, 'get_sync_filter': <function Model7260.get_sync_filter>, 'set_reserve': <function Model7260.set_reserve>, 'get_reserve': <function Model7260.get_reserve>, 'AC_GAIN': [0, 10, 20, 30, 40, 50, 60, 70, 80, 90], 'set_ac_gain_db': <function Model7260.set_ac_gain_db>, 'get_ac_gain_db': <function Model7260.get_ac_gain_db>, 'increase_ac_gain_db': <function Model7260.increase_ac_gain_db>, 'decrease_ac_gain_db': <function Model7260.decrease_ac_gain_db>, 'start_check_overloads': <function Model7260.start_check_overloads>, 'OVERLOADS': [None, 'CH1 Output', 'CH2 Output', 'Y Channel Output', 'X Channel Output', None, 'Input', 'Reference Unlock'], 'check_overloads': <function Model7260.check_overloads>, 'BUFFER_MAX_LENGTH': 32768, 'buffer_get_max_size': <function Model7260.buffer_get_max_size>, 'get_next_valid_sample_rate_Hz': <function Model7260.get_next_valid_sample_rate_Hz>, 'CBD_BITS': ['X', 'Y', 'MAG', 'PHASE', 'SENS', 'ADC1', 'ADC2'], 'CBD_BITS_SR830': ['X', 'Y', 'R', 'theta', 'SENS', 'Aux In 1', 'Aux In 2'], 'buffer_setup': <function Model7260.buffer_setup>, 'buffer_start_fill': <function Model7260.buffer_start_fill>, 'buffer_stop_fill': <function Model7260.buffer_stop_fill>, 'buffer_is_done': <function Model7260.buffer_is_done>, 'buffer_get_n_points': <function Model7260.buffer_get_n_points>, 'buffer_get_data': <function Model7260.buffer_get_data>, '_buffer_get_columns': <function Model7260._buffer_get_columns>, '_buffer_get_single_column': <function Model7260._buffer_get_single_column>, '_buffer_convert_from_full_scale': <function Model7260._buffer_convert_from_full_scale>, 'auto_sensitivity': <function Model7260.auto_sensitivity>, 'auto_gain': <function Model7260.auto_gain>, '_enumerate_devices': <staticmethod(<function Model7260._enumerate_devices>)>, 'connect_device': <staticmethod(<function Model7260.connect_device>)>, '__repr__': <function Model7260.__repr__>, '__static_attributes__': ('_buffer_cbd', '_buffer_length', '_buffer_what', 'instr'), '__abstractmethods__': frozenset(), '_abc_impl': <_abc._abc_data object>, '_children': {}, '_manual_devices': []})#
__firstlineno__ = 12#
__init__(instr, check_front_switch=True)[source]#
__module__ = 'devctrl.devices.lock_in.impl.model7260'#
__repr__()[source]#
Returns:

The name of the device. If applicable, this should include serial port, GPIB address, etc.

__slots__ = ()#
__static_attributes__ = ('_buffer_cbd', '_buffer_length', '_buffer_what', 'instr')#
__weakref__#

list of weak references to the object

_abc_impl = <_abc._abc_data object>#
_buffer_convert_from_full_scale(data)[source]#

Convert values from full-scale to Volts and Degrees

See section 6.4.09 on page 141 in the manual

Parameters:

data – full scale data, ordered according to the parameter “what” of buffer_setup

Returns:

data converted to Volt and Degrees

_buffer_get_columns(cbd: int, bits_to_output_order: list[int], n_points: int, data: ndarray)[source]#

Request multiple columns :param cbd: A bitmask of the columns to get :param bits_to_output_order: Value is index of the n-th set cbd bit in the output array, and index is n :param n_points: Number of data points that are expected to be returned. Must be the same value the buffer was set to. :param data: A numpy array to put the output data in

_buffer_get_single_column(column_bit_nr, n_points, data, data_idx)[source]#

Request a single column of the curve in the buffer :param column_bit_nr: Bit number corresponding to column, see 6-23 in the manual :param n_points: Number of data points that are expected to be returned. Must be the same value the buffer was set to. :param data_idx: The index of the column in the output array :param data: A numpy array to put the output data in :return:

_children = {}#
_dummies_only = False#
static _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()#
auto_gain()[source]#
auto_sensitivity()[source]#
buffer_get_data(start=0, n_points: int | None = None, raw=False)[source]#

Get the data from the buffer. Note that regardless of start and n_points, the whole buffer has to be transmitted every time. Doing it piece-wise for increased performance is thus useless. :return:

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_get_n_points(dont_log=True) int[source]#

Query the number of points in the buffer :return:

buffer_is_done() bool[source]#

Check if the target number of points are in the buffer

buffer_setup(what=['R', 'Aux In 1'], length=None, sample_rate_Hz=256)[source]#

Compatibility function with same syntax as SR830 :param what: Quantities to measure. The Model7260 can measure more than 2 at a time! :param length: Number of values to measure or None to fill the buffer to the maximum.

The max length depends on how many quantities are measured.

Parameters:

sample_rate – This will be converted to a measurement interval and rounded to 5 ms. So you might not get the exact same sample rate as with the SR830, but you can choose arbitrary values.

buffer_start_fill()[source]#

Start a buffer measurement that was previously configured with buffer_setup()

buffer_stop_fill()[source]#

Stop the current buffer measurement

check_overloads() str[source]#

Check the overload status byte

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 occurred

check_status() str[source]#

Check the device status

Queries the status byte and reports any error conditions. Only reports bad status bits, returning an empty string if everything is OK.

Returns:

Empty string if all good, otherwise description of what is wrong

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

static connect_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_ac_gain_db() float[source]#
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

get_ac_gain_db()[source]#
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_filter_slope()[source]#
get_frequency_Hz() float[source]#
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_reference_trigger()[source]#
get_reserve()[source]#
get_sensitivity_volt()[source]#
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

get_sync_filter()[source]#

TODO: Actually is Synchronous time constant control and not a filter

get_time_constant_s()[source]#
static get_wait_time_s(time_const: float, filter_slope: int)[source]#

see read_get_wait_time_s

increase_ac_gain_db() float[source]#
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

is_connected() bool[source]#

Query whether the device is (still) connected

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

party()[source]#
query(query, dont_log=False)[source]#
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

reset()[source]#
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, timeout_ms=3000)[source]#

Run a command and check for errors

Executes a command and monitors the status byte for errors or timeouts. Raises RuntimeError for invalid commands, parameter errors, or timeouts.

Parameters:
  • cmd – SCPI command to execute

  • timeout_ms – Maximum time to wait for command completion in milliseconds

Raises:
  • RuntimeError – For various error conditions detected via status byte

  • pyvisa.VisaIOError – If VISA communication fails

set_ac_gain_db(gain_db)[source]#
set_default_display()[source]#
set_filter_slope(slope_db_oct)[source]#
set_frequency_Hz(frequency_Hz)[source]#
set_reference(reference)[source]#
set_reference_trigger(trigger)[source]#
set_reserve(reserve)[source]#
set_sensitivity_volt(volt)[source]#
set_sync_filter(sync)[source]#
set_time_constant_s(dt)[source]#
start_check_overloads()[source]#
try_recover_from_communication_error(original_error)[source]#

Try to get into a normal state by flushing the output queue and reading the instrument status