Skip to content

Commit

Permalink
Updates to get everything working for a terascan measurement. I belie…
Browse files Browse the repository at this point in the history
…ve it all works as intended now. Next steps are getting the diffraction grating to work correctly.
  • Loading branch information
lange50 committed Mar 13, 2025
1 parent fddd6ae commit 42a867b
Show file tree
Hide file tree
Showing 17 changed files with 1,187 additions and 3,496 deletions.
48 changes: 7 additions & 41 deletions cfg/terascan.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ logic:
module.Class: 'terascan_logic.TerascanLogic'
connect:
laser: scanning_laser_logic
wavemeter: time_series_reader_logic
wavemeter: wavemeter_logic
counter: fast_counter_logic
daq: daq_reader_logic # Note that this logic assumes there is exactly one (digital) input to the DAQ.
options:
Expand All @@ -53,19 +53,15 @@ logic:
daq_reader_logic:
module.Class: 'common.daq_reader_logic.DAQReaderLogic'
connect:
daq: nidaq #daq_reader_dummy
daq: nidaq # daq_reader_dummy
options:
update_interval: 0 # Period in ms to check for data updates. Integers only. 0 is as fast as possible


time_series_reader_logic:
module.Class: 'common.data_in_stream_logic.DataInStreamLogic'
options:
max_frame_rate: 20 # optional (default: 20Hz)
channel_buffer_size: 1048576 # optional (default: 1MSample)
max_raw_data_bytes: 1073741824 # optional (default: 1GB)
wavemeter_logic:
module.Class: 'common.wavemeter_logic.WavemeterLogic'
connect:
streamer: wavemeter # instream_dummy
wavemeter: wavemeter # wavemeter_dummy


fast_counter_logic:
Expand Down Expand Up @@ -96,23 +92,9 @@ hardware:
type: 0 # 0 for Digital, 1 for Analog
name: 'line0' # The name as idintified by the card
port: 1 # port number identified by the card

wavemeter_proxy:
module.Class: 'wavemeter.high_finesse_proxy.HighFinesseProxy'
options:
watchdog_interval: 1.0 # how often the watchdog checks for errors/changes in s
dllPath: 'C:\Program Files (x86)\HighFinesse\Wavelength Meter WS6 3167\Projects\64\wlmData.dll'

wavemeter:
module.Class: 'wavemeter.high_finesse_wavemeter.HighFinesseWavemeter'
connect:
proxy: wavemeter_proxy
options:
channels:
laser:
switch_ch: 1 # channel on the wavemeter switch
unit: 'm' # wavelength (m) or frequency (Hz)
exposure: 10 # exposure time in ms, optional

swabian_timetagger:
module.Class: 'timetagger.swabian_tagger.SwabianTimeTagger'
Expand All @@ -133,27 +115,11 @@ hardware:
daq_reader_dummy:
module.Class: 'dummy.daq_reader_dummy.DAQReaderDummy'

instream_dummy:
module.Class: 'dummy.data_instream_dummy.InStreamDummy'
options:
channel_names:
- 'digital 1'
- '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'

fast_counter_dummy:
module.Class: 'dummy.fast_counter_dummy.FastCounterDummy'

wavemeter_dummy:
module.Class: 'dummy.wavemeter_dummy.WavemeterDummy'

scanning_laser_dummy:
module.Class: 'dummy.scanning_laser_dummy.ScanningLaserDummy'
Expand Down
72 changes: 59 additions & 13 deletions src/qudi/gui/terascan/terascan_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
__all__ = ['TerascanGui']

import numpy as np
from PySide2 import QtCore
import os
from PySide2 import QtCore, QtGui
from typing import List

from qudi.util.datastorage import TextDataStorage
from qudi.core.module import GuiBase
from qudi.core.connector import Connector
from qudi.core.statusvariable import StatusVar
from qudi.gui.terascan.terascan_main_window import TerascanMainWindow
from qudi.util.paths import get_artwork_dir

from qudi.logic.terascan_logic import TerascanData

Expand Down Expand Up @@ -61,6 +63,10 @@ def on_activate(self) -> None:
self._terascan_logic().sigScanFinished.connect(
self._scan_finished, QtCore.Qt.QueuedConnection
)

self._terascan_logic().sigLaserLocked.connect(
self._laser_lock_ui, QtCore.Qt.QueuedConnection
)


# Outputs:
Expand All @@ -76,6 +82,11 @@ def on_activate(self) -> None:
)

self._data = []

# Turn on update timer:
self.__timer = QtCore.QTimer()
self.__timer.setSingleShot(False)
self.__timer.timeout.connect(self._update_plot)

# Show the main window and raise it above all others
self.show()
Expand All @@ -85,6 +96,7 @@ def on_deactivate(self) -> None:
self._terascan_logic().sigWavelengthUpdated.disconnect(self._wavelength_changed)
self._terascan_logic().sigCountsUpdated.disconnect(self._receive_data)
self._terascan_logic().sigScanFinished.disconnect(self._scan_finished)
self._terascan_logic().sigLaserLocked.disconnect(self._laser_lock_ui)

# Use "plain" disconnects (without argument) only on signals owned by this module
self._mw.start_wavelength.valueChanged.disconnect()
Expand All @@ -94,8 +106,14 @@ def on_deactivate(self) -> None:
self.sigStopMeasurement.disconnect()
self.sigSetWavelengths.disconnect()

# disable update timer:
self.__timer.stop()
self.__timer.timeout.disconnect()
self.__timer = None

# Close main window
self._mw.close()


def show(self) -> None:
""" Mandatory method to show the main window """
Expand All @@ -107,6 +125,7 @@ def _start_changed(self, wave: float) -> None:
""" Qt slot to be called upon wavelength change """
self._start_wavelength = wave
self.sigSetWavelengths.emit(self._start_wavelength, self._stop_wavelength)


@QtCore.Slot(float)
def _stop_changed(self, wave: float) -> None:
Expand All @@ -119,34 +138,41 @@ def _stop_changed(self, wave: float) -> None:
def _start_stop_pressed(self) -> None:
""" Qt slot to be called upon wavelength change """
if self._mw.start_stop_button.text() == 'Start Measurement':
self._update_ui(True)
self.__timer.start(250)
self.sigStartMeasurement.emit()
else:
self._update_ui(False)
self.__timer.stop()
self.sigStopMeasurement.emit()



def _update_ui(self, running: bool) -> None:
if running:
self._mw.start_stop_button.setText('Stop Measurement')
self._mw.plot_widget.setXRange(self._start_wavelength, self._stop_wavelength)
print('start measurement in terascan_gui')
self.sigStartMeasurement.emit()
self._mw._statusbar.clearMessage()
self._mw._progress_bar.setValue(0)

else:
self._mw.start_stop_button.setText('Start Measurement')
self.sigStopMeasurement.emit()
self._mw._statusbar.showMessage('Ready')

@QtCore.Slot()
def _scan_finished(self) -> None:
self._mw.start_stop_button.setText('Start Measurement')

@QtCore.Slot(object)
def _receive_data(self, data: List[TerascanData]) -> None:
img = np.zeros((len(data),2))
for i in range(len(data) - 1):
# print(np.average(data[i].counts))
img[i][0] = data[i].wavelength
img[i][1] = data[i].counts
# img[i][0] = 775 + 15 * np.random.rand()
# img[i][1] = 100 * np.random.rand()

self._mw.data_item.setData(x = img[:, 0], y = img[:, 1])
self._data = data


@QtCore.Slot(float)
def _wavelength_changed(self, wave: float) -> None:
self._current_wavelength = wave
percent = 100 * (wave*1e-3 - self._start_wavelength) / (self._stop_wavelength - self._start_wavelength);
self._mw._progress_bar.setValue(int(round(percent)))

@QtCore.Slot()
def _save_data(self) -> None:
Expand All @@ -156,3 +182,23 @@ def _save_data(self) -> None:
)

ds.save_data(self._data)

@QtCore.Slot(bool)
def _laser_lock_ui(self, locked: bool) -> None:
icon = 'network-connect' if locked else 'network-disconnect'
pix = QtGui.QPixmap(os.path.join(get_artwork_dir(), 'icons', icon))
self._mw._locked_indicator.setPixmap(pix.scaled(16, 16))



def _update_plot(self) -> None:
if (len(self._data) == 0):
return

img = np.zeros((len(self._data),2))
for i in range(len(self._data) - 1):
img[i][0] = self._data[i].wavelength*1e-3
img[i][1] = self._data[i].counts

self._mw.data_item.setData(x = img[:, 0], y = img[:, 1])

24 changes: 14 additions & 10 deletions src/qudi/gui/terascan/terascan_main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,20 @@ def __init__(self, *args, **kwargs):
menu.addAction(self.action_close)
self.setMenuBar(menu_bar)

# Create toolbar
# toolbar = QtWidgets.QToolBar()
# toolbar.setAllowedAreas(QtCore.Qt.AllToolBarAreas)
# self.action_start_video = QtWidgets.QAction('Start Video')
# self.action_start_video.setCheckable(True)
# toolbar.addAction(self.action_start_video)
# self.action_capture_frame = QtWidgets.QAction('Capture Frame')
# self.action_capture_frame.setCheckable(True)
# toolbar.addAction(self.action_capture_frame)
# self.addToolBar(QtCore.Qt.TopToolBarArea, toolbar)
# Create statusbar and indicators
self._statusbar = self.statusBar()
self._statusbar.showMessage('Ready')

self._progress_bar = QtWidgets.QProgressBar()
self._progress_bar.setRange(0, 100)
self._progress_bar.setValue(0)


self._locked_indicator = QtWidgets.QLabel()
self._locked_indicator.setPixmap(QtGui.QPixmap(os.path.join(get_artwork_dir(), 'icons', 'network-disconnect')).scaled(16, 16))

self._statusbar.addWidget(self._locked_indicator)
self._statusbar.addWidget(self._progress_bar)

# Initialize widgets
self.start_stop_button = QtWidgets.QPushButton('Start Measurement')
Expand Down
Loading

0 comments on commit 42a867b

Please sign in to comment.