Replies: 1 comment 2 replies
-
Hi! Thanks for your interest in Qudi. This is a use-case that is already supported. I think you may have a mistake in your config file. Can you share that here? Here's a dummy config for a confocal with two arms i.e. one NI card controls one xyz stage and another NI card controls a 4f scanner. Below this dummy is also a real config file that should work for the same. It's important to note that the Having said that, there are still a few bugs to iron out. You may experience crashes/ errors if you run both the counters and both the confocal scanners simultaneously. We welcome PRs to address these. Let us know if this works for you! gui:
counter_normal:
module.Class: 'time_series.time_series_gui.TimeSeriesGui'
options:
use_antialias: True # optional, set to False if you encounter performance issues
connect:
_time_series_logic_con: time_series_reader_logic_normal
counter_4f:
module.Class: 'time_series.time_series_gui.TimeSeriesGui'
options:
use_antialias: True # optional, set to False if you encounter performance issues
connect:
_time_series_logic_con: time_series_reader_logic_4f
scanner_normal:
module.Class: 'scanning.scannergui.ScannerGui'
options:
image_axes_padding: 0.02
default_position_unit_prefix: 'u' # optional, use unit prefix characters, e.g. 'u' or 'n'
optimizer_plot_dimensions: [2,1]
connect:
scanning_logic: scanning_probe_logic_normal
data_logic: scanning_data_logic_normal
optimize_logic: scanning_optimize_logic_normal
scanner_4f:
module.Class: 'scanning.scannergui.ScannerGui'
options:
image_axes_padding: 0.02
default_position_unit_prefix: 'u' # optional, use unit prefix characters, e.g. 'u' or 'n'
optimizer_plot_dimensions: [2,1]
connect:
scanning_logic: scanning_probe_logic_4f
data_logic: scanning_data_logic_4f
optimize_logic: scanning_optimize_logic_4f
logic:
time_series_reader_logic_normal:
module.Class: 'time_series_reader_logic.TimeSeriesReaderLogic'
options:
max_frame_rate: 20 # optional (10Hz by default)
calc_digital_freq: True # optional (True by default)
connect:
streamer: ni_instreamer_normal
time_series_reader_logic_4f:
module.Class: 'time_series_reader_logic.TimeSeriesReaderLogic'
options:
max_frame_rate: 20 # optional (10Hz by default)
calc_digital_freq: True # optional (True by default)
connect:
streamer: ni_instreamer_4f
scanning_probe_logic_normal:
module.Class: 'scanning_probe_logic.ScanningProbeLogic'
options:
max_history_length: 20
max_scan_update_interval: 2
position_update_interval: 1
connect:
scanner: ni_scanner_normal
scanning_probe_logic_4f:
module.Class: 'scanning_probe_logic.ScanningProbeLogic'
options:
max_history_length: 20
max_scan_update_interval: 2
position_update_interval: 1
connect:
scanner: ni_scanner_4f
scanning_data_logic_normal:
module.Class: 'scanning_data_logic.ScanningDataLogic'
options:
max_history_length: 20
connect:
scan_logic: scanning_probe_logic_normal
scanning_data_logic_4f:
module.Class: 'scanning_data_logic.ScanningDataLogic'
options:
max_history_length: 20
connect:
scan_logic: scanning_probe_logic_4f
scanning_optimize_logic_normal:
module.Class: 'scanning_optimize_logic.ScanningOptimizeLogic'
connect:
scan_logic: scanning_probe_logic_normal
scanning_optimize_logic_4f:
module.Class: 'scanning_optimize_logic.ScanningOptimizeLogic'
connect:
scan_logic: scanning_probe_logic_4f
hardware:
ni_instreamer_normal:
module.Class: 'dummy.data_instream_dummy.InStreamDummy'
options:
device_name: 'Dev1'
channel_names: # optional
- 'PFI8'
channel_signals: # Can be 'counts' or 'sine'
- 'counts'
channel_units:
- 'Hz'
adc_voltage_range: [0, 10] # optional
max_channel_samples_buffer: 10000000 # optional
read_write_timeout: 10 # optional
ni_instreamer_4f:
module.Class: 'dummy.data_instream_dummy.InStreamDummy'
options:
device_name: 'Dev2'
channel_names: # optional
- 'PFI8'
channel_signals: # Can be 'counts' or 'sine'
- 'counts'
channel_units:
- 'Hz'
adc_voltage_range: [0, 10] # optional
max_channel_samples_buffer: 10000000 # optional
read_write_timeout: 10 # optional
ni_scanner_normal:
module.Class: 'dummy.scanning_probe_dummy.ScanningProbeDummy'
options:
position_ranges:
'x': [0, 200e-6]
'y': [0, 200e-6]
'z': [-100e-6, 100e-6]
frequency_ranges:
'x': [0, 10000]
'y': [0, 10000]
'z': [0, 5000]
resolution_ranges:
'x': [2, 2147483647]
'y': [2, 2147483647]
'z': [2, 2147483647]
position_accuracy:
'x': 10e-9
'y': 10e-9
'z': 50e-9
spot_density: 1e11
ni_scanner_4f:
module.Class: 'dummy.scanning_probe_dummy.ScanningProbeDummy'
options:
position_ranges:
'x': [0, 200e-6]
'y': [0, 200e-6]
'z': [-100e-6, 100e-6]
frequency_ranges:
'x': [0, 10000]
'y': [0, 10000]
'z': [0, 5000]
resolution_ranges:
'x': [2, 2147483647]
'y': [2, 2147483647]
'z': [2, 2147483647]
position_accuracy:
'x': 10e-9
'y': 10e-9
'z': 50e-9
spot_density: 1e11
ni_io_normal:
module.Class: 'dummy.finite_sampling_io_dummy.FiniteSamplingIODummy'
options:
sample_rate_limits: [1, 1e6]
frame_size_limits: [1, 1e9]
default_output_mode: 'JUMP_LIST'
input_channel_units:
'APD counts': 'c/s'
'Photodiode': 'V'
output_channel_units:
'Frequency': 'Hz'
'Voltage': 'V'
ni_ao_normal:
module.Class: 'dummy.finite_sampling_output_dummy.FiniteSamplingOutputDummy'
options:
sample_rate_limits: [1, 1e6]
frame_size_limits: [1, 1e9]
output_mode: 'JUMP_LIST'
channel_units:
'Frequency': 'Hz'
'Voltage': 'V'
ni_io_4f:
module.Class: 'dummy.finite_sampling_io_dummy.FiniteSamplingIODummy'
options:
sample_rate_limits: [1, 1e6]
frame_size_limits: [1, 1e9]
default_output_mode: 'JUMP_LIST'
input_channel_units:
'APD counts': 'c/s'
'Photodiode': 'V'
output_channel_units:
'Frequency': 'Hz'
'Voltage': 'V'
ni_ao_4f:
module.Class: 'dummy.finite_sampling_output_dummy.FiniteSamplingOutputDummy'
options:
sample_rate_limits: [1, 1e6]
frame_size_limits: [1, 1e9]
output_mode: 'JUMP_LIST'
channel_units:
'Frequency': 'Hz'
'Voltage': 'V' Here's a real config file for actual hardware gui:
counter_normal:
module.Class: 'time_series.time_series_gui.TimeSeriesGui'
options:
use_antialias: True # optional, set to False if you encounter performance issues
connect:
_time_series_logic_con: time_series_reader_logic_normal
counter_4f:
module.Class: 'time_series.time_series_gui.TimeSeriesGui'
options:
use_antialias: True # optional, set to False if you encounter performance issues
connect:
_time_series_logic_con: time_series_reader_logic_4f
scanner_normal:
module.Class: 'scanning.scannergui.ScannerGui'
options:
image_axes_padding: 0.02
default_position_unit_prefix: 'u' # optional, use unit prefix characters, e.g. 'u' or 'n'
optimizer_plot_dimensions: [2,1]
connect:
scanning_logic: scanning_probe_logic_normal
data_logic: scanning_data_logic_normal
optimize_logic: scanning_optimize_logic_normal
scanner_4f:
module.Class: 'scanning.scannergui.ScannerGui'
options:
image_axes_padding: 0.02
default_position_unit_prefix: 'u' # optional, use unit prefix characters, e.g. 'u' or 'n'
optimizer_plot_dimensions: [2,1]
connect:
scanning_logic: scanning_probe_logic_4f
data_logic: scanning_data_logic_4f
optimize_logic: scanning_optimize_logic_4f
logic:
time_series_reader_logic_normal:
module.Class: 'time_series_reader_logic.TimeSeriesReaderLogic'
options:
max_frame_rate: 20 # optional (10Hz by default)
calc_digital_freq: True # optional (True by default)
connect:
streamer: ni_instreamer_normal
time_series_reader_logic_4f:
module.Class: 'time_series_reader_logic.TimeSeriesReaderLogic'
options:
max_frame_rate: 20 # optional (10Hz by default)
calc_digital_freq: True # optional (True by default)
connect:
streamer: ni_instreamer_4f
scanning_probe_logic_normal:
module.Class: 'scanning_probe_logic.ScanningProbeLogic'
options:
max_history_length: 20
max_scan_update_interval: 2
position_update_interval: 1
connect:
scanner: ni_scanner_normal
scanning_probe_logic_4f:
module.Class: 'scanning_probe_logic.ScanningProbeLogic'
options:
max_history_length: 20
max_scan_update_interval: 2
position_update_interval: 1
connect:
scanner: ni_scanner_4f
scanning_data_logic_normal:
module.Class: 'scanning_data_logic.ScanningDataLogic'
options:
max_history_length: 20
connect:
scan_logic: scanning_probe_logic_normal
scanning_data_logic_4f:
module.Class: 'scanning_data_logic.ScanningDataLogic'
options:
max_history_length: 20
connect:
scan_logic: scanning_probe_logic_4f
scanning_optimize_logic_normal:
module.Class: 'scanning_optimize_logic.ScanningOptimizeLogic'
connect:
scan_logic: scanning_probe_logic_normal
scanning_optimize_logic_4f:
module.Class: 'scanning_optimize_logic.ScanningOptimizeLogic'
connect:
scan_logic: scanning_probe_logic_4f
hardware:
ni_instreamer_normal:
module.Class: 'ni_x_series.ni_x_series_in_streamer.NIXSeriesInStreamer'
options:
device_name: 'Dev1'
digital_sources: # optional
- 'PFI8'
adc_voltage_range: [0, 10] # optional
max_channel_samples_buffer: 10000000 # optional
read_write_timeout: 10 # optional
ni_instreamer_4f:
module.Class: 'ni_x_series.ni_x_series_in_streamer.NIXSeriesInStreamer'
options:
device_name: 'Dev2'
digital_sources: # optional
- 'PFI8'
adc_voltage_range: [0, 10] # optional
max_channel_samples_buffer: 10000000 # optional
read_write_timeout: 10 # optional
ni_scanner_normal:
module.Class: 'interfuse.ni_scanning_probe_interfuse.NiScanningProbeInterfuse'
connect:
scan_hardware: 'ni_io_normal'
analog_output: 'ni_ao_normal'
options:
ni_channel_mapping:
x: 'ao0'
y: 'ao1'
z: 'ao2'
APD1: 'PFI8'
position_ranges: # in m
x: [0, 200e-6]
y: [0, 200e-6]
z: [0, 200e-6]
frequency_ranges:
x: [1, 500]
y: [1, 500]
z: [1, 500]
resolution_ranges:
x: [1, 1000]
y: [1, 1000]
z: [1, 1000]
input_channel_units:
APD1: 'c/s'
backwards_line_resolution: 50 # optional
maximum_move_velocity: 400e-6 #m/s
ni_scanner_4f:
module.Class: 'interfuse.ni_scanning_probe_interfuse.NiScanningProbeInterfuse'
connect:
scan_hardware: 'ni_io_4f'
analog_output: 'ni_ao_4f'
options:
ni_channel_mapping:
x: 'ao0'
y: 'ao1'
z: 'ao2'
APD2: 'PFI8'
position_ranges: # in m
x: [0, 201e-6]
y: [0, 201e-6]
z: [0, 201e-6]
frequency_ranges:
x: [1, 500]
y: [1, 500]
z: [1, 500]
resolution_ranges:
x: [1, 1000]
y: [1, 1000]
z: [1, 1000]
input_channel_units:
APD2: 'c/s'
backwards_line_resolution: 50 # optional
maximum_move_velocity: 400e-6 #m/s
ni_io_normal:
module.Class: 'ni_x_series.ni_x_series_finite_sampling_io.NIXSeriesFiniteSamplingIO'
options:
device_name: 'Dev1'
input_channel_units: # optional
PFI8: 'c/s'
output_channel_units:
'ao0': 'V'
'ao1': 'V'
'ao2': 'V'
adc_voltage_ranges:
ai0: [0, 10] # optional
ai1: [0, 10] # optional
ai2: [0, 10] # optional
output_voltage_ranges:
ao0: [0, 10]
ao1: [0, 10]
ao2: [0, 10]
frame_size_limits: [1, 1e9] # optional #TODO actual HW constraint?
output_mode: 'JUMP_LIST' #'JUMP_LIST' # optional, must be name of SamplingOutputMode
read_write_timeout: 10 # optional
ni_ao_normal:
module.Class: 'ni_x_series.ni_x_series_analog_output.NIXSeriesAnalogOutput'
options:
device_name: 'Dev1'
channels:
ao0:
limits: [0.0, 10.0]
keep_value: True
ao1:
limits: [0.0, 10.0]
keep_value: True
ao2:
limits: [0.0, 10.0]
keep_value: True
ni_io_4f:
module.Class: 'ni_x_series.ni_x_series_finite_sampling_io.NIXSeriesFiniteSamplingIO'
options:
device_name: 'Dev2'
input_channel_units: # optional
PFI8: 'c/s'
output_channel_units:
'ao0': 'V'
'ao1': 'V'
'ao2': 'V'
adc_voltage_ranges:
ai0: [0, 10] # optional
ai1: [0, 10] # optional
ai2: [0, 10] # optional
output_voltage_ranges:
ao0: [0, 10]
ao1: [0, 10]
ao2: [0, 10]
frame_size_limits: [1, 1e9] # optional #TODO actual HW constraint?
output_mode: 'JUMP_LIST' #'JUMP_LIST' # optional, must be name of SamplingOutputMode
read_write_timeout: 10 # optional
ni_ao_4f:
module.Class: 'ni_x_series.ni_x_series_analog_output.NIXSeriesAnalogOutput'
options:
device_name: 'Dev2'
channels:
ao0:
limits: [0.0, 10.0]
keep_value: True
ao1:
limits: [0.0, 10.0]
keep_value: True
ao2:
limits: [0.0, 10.0]
keep_value: True |
Beta Was this translation helpful? Give feedback.
-
Hi guys,
I'm currently setting up qudi (scanning setup) to work with a NI USB-6212 (BNC) and NI-USB 6346 card, each providing only two analog output channels (ao0 and ao1). I want to preserve the full functionality and all capabilities that are available when using just a single NI device with 4 analog outputs. So all of qudi’s scanning, motion, and data acquisition features should remain intact.
The main challenge I think is that qudi and its modules, such as the scanning_probe_logic, ni_scanning_probe_interfuse, ni_x_series_finite_sampling_io, and ni_x_series_analog_output modules, were originally designed with the expectation of a single device providing all required channels. The configuration files and internal logic currently assume a single device name, and attempts to simply provide multiple device names in the configuration have led to errors indicating that channels could not be recognized or that device names were invalid and countless more.
I’ve had the idea of creating a virtual NI device that aggregates both physical devices into one logical device, but as far as I know, NI MAX or DAQmx does not offer a straightforward way to virtually combine two separate devices into a single unified device with a continuous set of AO channels.
Before making deep modifications to the qudi codebase, I want to be sure there is no simpler or more elegant solution. Perhaps there is a known NI MAX or DAQmx feature that allows device aliasing or channel remapping in a way that is transparent to qudi and works for my specific purpose.
I'm rather new to qudi so maybe (I hope) I am missing something and there is an easy way.
Thank you in advance for your help.
Beta Was this translation helpful? Give feedback.
All reactions