Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Laser Scanning Toolchain #169

Draft
wants to merge 80 commits into
base: main
Choose a base branch
from
Draft

Laser Scanning Toolchain #169

wants to merge 80 commits into from

Conversation

Neverhorst
Copy link
Member

@Neverhorst Neverhorst commented Nov 6, 2024

Description

This PR introduces a toolchain to visualize and process data from specialized streaming modules based on DataInStreamInterface that contain one stream channel with laser frequency (Hz) or wavelength (m) data.
Optionally, it can also connect to a ScannableLaserInterface hardware implementation to actively control laser scanning (settings/start/stop) during data acquisition.
In the absence of a scannable laser hardware module, the data stream is just recorded and the actual laser scanning is assumed to be controlled from elsewhere.

Additionally this PR introduces tooling and interfuse modules to distribute DataInStreamInterface data streams to multiple qudi modules in mixed local/remote environments.

Motivation and Context

Incorporates and expands changes proposed in PRs #132 and #120 into a complete toolchain solution.
These PRs as well as their branches wavemeter_scanning and scannable_laser_interface can be safely deleted upon merging this PR.

Fixes Issue #59

For more information about using this toolchain, please refer to the new documentation setup_laserscanning.md and in extension setup_instream_buffer.md and setup_instream_sync.md.

How Has This Been Tested?

So far only with dummy modules ScannableLaserDummy and InStreamDummy in a remote module setup (2 qudi processes).
You can use these configs as a starting point for tests:

laserscanning_test_remote.cfg
global:
    # list of modules to load when starting
    startup: []

    remote_modules_server:
        address: 'localhost'
        port: 12345

    namespace_server_port: 18862

    force_remote_calls_by_value: True

    ## For controlling the appearance of the GUI:
    stylesheet: 'qdark.qss'

hardware:
    instream_dummy:
        module.Class: 'dummy.data_instream_dummy.InStreamDummy'
        allow_remote: True
        options:
            channel_names:
                - 'APD'
                #- 'analog 1'
                #- 'digital 2'
            channel_units:
                - 'Hz'
                #- 'V'
                #- 'Hz'
            channel_signals:  # Can be 'counts' or 'sine'
                - 'counts'
                #- 'sine'
                #- 'counts'
            data_type: 'float64'
            sample_timing: 'CONSTANT'  # Can be 'CONSTANT', 'TIMESTAMP' or 'RANDOM'

    wavemeter_dummy:
        module.Class: 'dummy.data_instream_dummy_wavemeter.InStreamDummy'
        allow_remote: True
        options:
            channel_names:
                - 'Wavemeter'
            channel_units:
                - 'm'
            channel_signals:  # Can be 'counts' or 'sine'
                - 'counts'
            data_type: 'float64'
            sample_timing: 'TIMESTAMP'  # Can be 'CONSTANT', 'TIMESTAMP' or 'RANDOM'
            
    scannable_laser_dummy:
        module.Class: 'dummy.scannable_laser_dummy.ScannableLaserDummy'
        allow_remote: True
laserscanning_test_local.cfg
global:
    # list of modules to load when starting
    startup: []

    namespace_server_port: 18861

    force_remote_calls_by_value: True

    ## For controlling the appearance of the GUI:
    stylesheet: 'qdark.qss'

gui:
    time_series_wavemeter:
        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_wavemeter_logic
            
    time_series_counter:
        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_counter_logic
            
    time_series_combined:
        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_combined_logic

    laser_scanning_gui:
        module.Class: 'laserscanning.laser_scanning_gui.LaserScanningGui'
        options:
            max_display_points: 1000
        connect:
            laser_scanning_logic: laser_scanning_logic

logic:
    time_series_wavemeter_logic:
        module.Class: 'time_series_reader_logic.TimeSeriesReaderLogic'
        options:
            max_frame_rate: 30  # optional (10Hz by default)
            channel_buffer_size: 1048576  # optional (default: 1MSample)
            calc_digital_freq: True  # optional (True by default)
        connect:
            streamer: wavemeter_buffer2

    time_series_counter_logic:
        module.Class: 'time_series_reader_logic.TimeSeriesReaderLogic'
        options:
            max_frame_rate: 30  # optional (10Hz by default)
            channel_buffer_size: 1048576  # optional (default: 1MSample)
            calc_digital_freq: True  # optional (True by default)
        connect:
            streamer: counter_buffer2
            
    time_series_combined_logic:
        module.Class: 'time_series_reader_logic.TimeSeriesReaderLogic'
        options:
            max_frame_rate: 30  # optional (10Hz by default)
            channel_buffer_size: 1048576  # optional (default: 1MSample)
            calc_digital_freq: False  # optional (True by default)
        connect:
            streamer: combined_buffer2

    laser_scanning_logic:
        module.Class: 'laser_scanning_logic.LaserScanningLogic'
        options:
            max_update_rate: 30
            max_samples: 100000000
            laser_channel: Wavemeter
        connect:
            streamer: combined_buffer1
            laser: scannable_laser_dummy 

hardware:
    wavemeter_sync_interfuse:
        module.Class: 'interfuse.instream_sync.DataInStreamSync'
        options:
            min_interpolation_samples: 3
            allow_overwrite: False
            delay_time:
            max_poll_rate: 60.0
        connect:
            primary_streamer: counter_buffer1
            secondary_streamer: wavemeter_buffer1
            
    counter_buffer1:
        module.Class: 'interfuse.instream_buffer.DataInStreamBuffer'
        options:
            allow_overwrite: False
            max_poll_rate: 60.0
        connect:
            streamer: instream_dummy
            
    counter_buffer2:
        module.Class: 'interfuse.instream_buffer.DataInStreamBuffer'
        options:
            allow_overwrite: False
            max_poll_rate: 60.0
        connect:
            streamer: instream_dummy
            
    wavemeter_buffer1:
        module.Class: 'interfuse.instream_buffer.DataInStreamBuffer'
        options:
            allow_overwrite: False
            max_poll_rate: 60.0
        connect:
            streamer: wavemeter_dummy
            
    wavemeter_buffer2:
        module.Class: 'interfuse.instream_buffer.DataInStreamBuffer'
        options:
            allow_overwrite: False
            max_poll_rate: 60.0
        connect:
            streamer: wavemeter_dummy
            
    combined_buffer1:
        module.Class: 'interfuse.instream_buffer.DataInStreamBuffer'
        options:
            allow_overwrite: False
            max_poll_rate: 60.0
        connect:
            streamer: wavemeter_sync_interfuse
            
    combined_buffer2:
        module.Class: 'interfuse.instream_buffer.DataInStreamBuffer'
        options:
            allow_overwrite: False
            max_poll_rate: 60.0
        connect:
            streamer: wavemeter_sync_interfuse

    instream_dummy:
        # module.Class: 'dummy.data_instream_dummy.InStreamDummy'
        # options:
        #     channel_names:
        #         - 'APD'
        #         #- 'analog 1'
        #         #- 'digital 2'
        #     channel_units:
        #         - 'Hz'
        #         #- 'V'
        #         #- 'Hz'
        #     channel_signals:  # Can be 'counts' or 'sine'
        #         - 'counts'
        #         #- 'sine'
        #         #- 'counts'
        #     data_type: 'float64'
        #     sample_timing: 'CONSTANT'  # Can be 'CONSTANT', 'TIMESTAMP' or 'RANDOM'
        native_module_name: 'instream_dummy'
        address: localhost
        port: 12345

    wavemeter_dummy:
        # module.Class: 'dummy.data_instream_dummy_wavemeter.InStreamDummy'
        # options:
        #     channel_names:
        #         - 'Wavemeter'
        #     channel_units:
        #         - 'm'
        #     channel_signals:  # Can be 'counts' or 'sine'
        #         - 'counts'
        #     data_type: 'float64'
        #     sample_timing: 'TIMESTAMP'  # Can be 'CONSTANT', 'TIMESTAMP' or 'RANDOM'
        native_module_name: 'wavemeter_dummy'
        address: localhost
        port: 12345
            
    scannable_laser_dummy:
        # module.Class: 'dummy.scannable_laser_dummy.ScannableLaserDummy'
        native_module_name: 'scannable_laser_dummy'
        address: localhost
        port: 12345

Important

Implementation and testing of actual hardware modules is needed before merging. Help is appreciated.

Screenshots:

image

Types of changes

  • Bug fix
  • New feature
  • Breaking change (Causes existing functionality to not work as expected)

Checklist:

  • My code follows the code style of this project.
  • I have documented my changes in /docs/changelog.md.
  • My change requires additional/updated documentation.
  • I have updated the documentation accordingly.
  • I have added/updated the config example for any module docstrings as necessary.
  • I have checked that the change does not contain obvious errors
    (syntax, indentation, mutable default values, etc.).
  • I have tested my changes using 'Load all modules' on the default dummy configuration.
  • All changed Jupyter notebooks have been stripped of their output cells.

…en trying to change anything in the streamer
Wavemeter_histogram_logic runs repeatatly by a QTqueued connection. This logic has access on the time series reader logic, while both are connected to their instreamer, respectively. It is to be checked if this implementation of logic being connected to logic is done properly. Moreover, the data acquistion/ synchronisation is implemented in the following way: The samples to read from the hardware are determined by the faster acquiring count instreamer. Upon this value the wavelength is then queried and directly interpolated in the hardware file as soon as at least one value is available. Thus a data array of equal size is generated. The time trace for the scatterplot is extracted from the wave instreamer.
-New gui file with subscript _2
-generating main window without QT Designer / .ui file
-Implemented InteractiveCurvesWidget such that the current laser position is visible as marker with the move_marker_selection method
-Implemented an axis toggle option between nm and Hz

The logic is changed in such a fashion that it needs the time series reader application to be running with only one digital channel. For this an additional signal in the time_series_reader_logic.py is added which emits only the most recent data points of the time series instreamer and is received in the wavemeter_histogram_logic.py.
-Implementation of saving, fitting, envelope, toggle of bottom dockwidget and autoscale histogram functionality
-Try to improve performance by introduced separate gui refresh rate and plotdataitem with the ability to set a downsampling. Further, first try of two separate start buttons is implemented.
GUI:
-Histogram region; show all data; added dockwidgets; restore default
LOGIC:
-Improved the binning of the histogram such that no empty bin; saving of envelope data
-Set up of remote connection; netobtain and new config (not commited)
-Hence hardware file cannot emit signal for current wavelength any more
-small adjustments for Gui
-Added name tag option for saving
-Enabled saving again while acqusition is running
-Added signal (sigStopWavemeter) in timer_series_logic to fix interplay. (When timeseries is stopped the wavemeter data acquisition is stopped.)
-Enabled fitting of envelope
commit changes in order to update main:
-mw anritsu, awg, unit.py, config
# Conflicts:
#	src/qudi/gui/time_series/time_series_gui.py
#	src/qudi/logic/time_series_reader_logic.py
-moved to newest version of the main branch (meaning that especially instream interface changes merged)
-added awg model
-config wavemeter_rework
-the high_finesse_wavemeter hardware module is the one from kilians pull request
-new logic&gui (wavemeter_scanning; naming has to be changed)
-in the timeseries logic solely a signal for the interplay is added
-high_finesse_constants version from kilian
-harxware module
-Get gated counting running and added predefined methods for pulsed ODMR and Rabi in sequence mode.
-Latest version of wavemeter_scanning_logic_3
… logic stop the qudi stream accordingly.

-Fully enabled NaNs for the histogram process and green GUI marker
# Conflicts:
#	src/qudi/hardware/wavemeter/high_finesse_constants.py
#	src/qudi/hardware/wavemeter/high_finesse_proxy.py
#	src/qudi/hardware/wavemeter/high_finesse_wavemeter.py
#	src/qudi/hardware/wavemeter/high_finesse_wrapper.py
…gic side

-generic stop signal from time_series_reader_logic.py
-formatting
@takuya-ulm takuya-ulm assigned takuya-ulm and unassigned takuya-ulm Dec 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants