DAQ+GUI: Work in progress

This commit is contained in:
2025-06-26 12:12:36 +02:00
parent 467d754a4f
commit 1d9c8133c1
12 changed files with 151 additions and 73 deletions
+8 -4
View File
@@ -21,6 +21,7 @@ from aaregui.panels.data_collection_settings import DataCollectionSettings
from aaregui.panels.sample_queue_panel import SampleQueuePanel
from aaregui.panels.tell_sample_panel import TellSamplePanel
from aaregui.scan_logic.raster_grid_manager import RasterGridManager
from aaregui.scan_logic.rotation_scan_manager import RotationScanManager
from aaregui.scan_logic.sample_mount_logic import SampleMountLogic
from aaregui.threads.camera_thread import SampleCameraThread
from aaregui.threads.daq_worker import DAQWorker
@@ -73,6 +74,7 @@ class MainWindow(QMainWindow):
)
self.raster = RasterGridManager(geom=geom)
self.rotation = RotationScanManager()
collection_controls_scroll = NoWheelScrollArea(top_widget)
@@ -130,8 +132,6 @@ class MainWindow(QMainWindow):
self.daq = DAQWorker(base_url=self.__base_url, token=self.__token)
self.daq.spreadsheet.connect(self.tell_samples.new_sample_list)
self.daq.raster_scan_completed.connect(self.raster.grid_scan_completed)
self.beamline.samcam.changed.connect(self.daq.samcam_settings)
self.beamline.loopctr.background.clicked.connect(self.daq.alc_background)
self.beamline.loopctr.find_tip.clicked.connect(self.daq.center_loop)
@@ -179,7 +179,7 @@ class MainWindow(QMainWindow):
self.daq.run_number_incremented.connect(self.data_collection.file_path_panel.increment_run_number)
self.job_list_panel.auto_scan.connect(self.daq.automated_scan)
self.daq.automated_scan_done.connect(self.job_list_panel.automated_scan_done)
self.job_list_panel.unmount.connect(self.daq.unmount)
self.tell_samples.mount.connect(self.daq.mount)
@@ -208,6 +208,7 @@ class MainWindow(QMainWindow):
self.status_bar.close_shutter.connect(self.daq.close_shutter)
self.status_bar.open_shutter.connect(self.daq.open_shutter)
self.raster.file_ready.connect(self.viewer.load_file)
self.rotation.file_ready.connect(self.viewer.load_file)
self.raster.image_selected.connect(self.viewer.load_image)
self.sample_logic.sample_changed.connect(self.data_collection.file_path_panel.update_sample)
@@ -227,7 +228,10 @@ class MainWindow(QMainWindow):
self.daq.update.connect(self.beamline.zoom_panel.update_daq_status)
self.daq.update.connect(self.beamline.beam_mark.update_daq_status)
self.daq.update.connect(self.sample_logic.update_daq_status)
self.daq.standard_scan_completed.connect(self.viewer.load_file)
self.daq.standard_scan_completed.connect(self.rotation.scan_completed)
self.daq.automated_scan_done.connect(self.job_list_panel.automated_scan_done)
self.daq.raster_scan_completed.connect(self.raster.grid_scan_completed)
def create_menu_bar(self):
"""Create a menu bar with File->Quit and Help->About."""
@@ -0,0 +1,41 @@
from PySide6.QtCore import Signal, Slot
from PySide6.QtWidgets import QWidget, QGridLayout, QLabel, QTextEdit, QPushButton
from aaredaqlib.models import SampleShortInfo
from aaregui.widgets.title_label import TitleLabel
class OmegaPanel(QWidget):
sample_manual = Signal(SampleShortInfo)
sample_clear = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self.__sample = SampleShortInfo(
db_id = -1,
puck_name="",
dewar_name="",
sample_name="Manual",
pin=0
)
grid_layout = QGridLayout(self)
grid_layout.addWidget(TitleLabel("Manual sample", self), 0, 0, 1, 2)
grid_layout.addWidget(QLabel("Name"), 1, 0)
self._text_name = QTextEdit(self.__sample.sample_name)
grid_layout.addWidget(self._text_name, 1, 1)
self._text_name.textChanged.connect(self._name_changed)
self._add_button = QPushButton("Add")
grid_layout.addWidget(self._add_button, 2, 0, 1 ,2)
self._add_button.clicked.connect(self._add_clicked)
@Slot(str)
def _name_vhanged(self, s: str):
self.__sample.sample_name = s
@Slot()
def _add_clicked(self):
self.sample_manual.emit(self.__sample)
@@ -37,7 +37,7 @@ class RotationDataCollectionPanel(ScanSettingsPanel):
self._layout.addWidget(QLabel("<br/><center><B><u>Screening</u></B></center>", parent=self), 4, 0, 1,6)
self._layout.addWidget(QLabel("Image angle", parent=self), 5, 0)
self.screening_image_angle = NumberLineEdit(0, 10.0, 0.5, decimals=3, parent=self)
self.screening_image_angle = NumberLineEdit(0, 90.0, 0.5, decimals=3, parent=self)
self._layout.addWidget(self.screening_image_angle, 5, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 5, 4)
@@ -10,6 +10,8 @@ from typing import List, Optional, Tuple
from aaredaqlib.coordinate import Coordinate, SmargonCoordinate
from aaredaqlib.models import DAQStatusModel
from aaredaqlib.raster_grid import RasterGridRequest, CompletedRasterGrid
from aaredaqlib.sample_geometry import SampleGeometryModel
class RasterGridMetric(Enum):
BKG = 0
@@ -74,11 +76,12 @@ class RasterGridManager(QObject):
file_ready = Signal(str)
image_selected = Signal(int)
def __init__(self, geom):
def __init__(self, geom: SampleGeometryModel):
super().__init__()
self.__sample_id = -1
self.__beam_size_mm = geom.beam_size_mm
self.__geom = geom
self.__metric = RasterGridMetric.SPOTS
@@ -120,7 +123,10 @@ class RasterGridManager(QObject):
self.__sample_id = s.sample.db_id
self.clear_completed_grids()
self.clear_active_grid()
if self.__beam_size_mm != s.geom.beam_size_mm:
self.__beam_size_mm = s.geom.beam_size_mm
self.__active_grid.grid_size_mm = Coordinate(x= 0.8 * self.__beam_size_mm.x,
y= 0.8 * self.__beam_size_mm.y)
self.__geom = s.geom
def resize_active_grid(self, end_point: QPointF):
@@ -272,7 +278,7 @@ class RasterGridManager(QObject):
grid = copy.deepcopy(self.__active_grid)
self.grid_scan.emit(grid)
@Slot()
@Slot(CompletedRasterGrid)
def grid_scan_completed(self, r: CompletedRasterGrid):
self.__completed_grids.append(r)
self.__active_grid.n_x = 0
@@ -1,6 +1,13 @@
from PySide6.QtCore import QObject
from PySide6.QtCore import QObject, Signal, Slot
from aaredaqlib.rotation_scan import CompletedRotationScan
class RotationScanManager(QObject):
file_ready = Signal(str)
@Slot(CompletedRotationScan)
def scan_completed(self, r: CompletedRotationScan):
if r.result.file_prefix is not None:
self.file_ready.emit(r.result.file_prefix)
pass
+26 -11
View File
@@ -9,7 +9,7 @@ from aaredaqlib.coordinate import SmargonCoordinate, Coordinate
from aaredaqlib.models import DAQStatusModel, SampleShortInfoList, SampleShortInfo, SampleCameraSettings, \
AutofocusSettings
from aaredaqlib.raster_grid import RasterGridRequest, CompletedRasterGrid
from aaredaqlib.rotation_scan import RotationScanRequest
from aaredaqlib.rotation_scan import RotationScanRequest, CompletedRotationScan
SPREADHSEET_FREQUENCY = 25 # Every 5 seconds
@@ -22,7 +22,7 @@ class DAQWorker(QObject):
automated_scan_done = Signal(int, bool) # sample ID, success
run_number_incremented = Signal()
raster_scan_completed = Signal(CompletedRasterGrid)
standard_scan_completed = Signal(str)
standard_scan_completed = Signal(CompletedRotationScan)
def __init__(self, base_url: str | None, token: str, parent=None):
super().__init__(parent)
@@ -195,18 +195,25 @@ class DAQWorker(QObject):
def move_smargon(self, coord: SmargonCoordinate):
self.generic_put("beamline/smargon", coord.model_dump_json())
def handle_rotation_scan_response(self, reply: QNetworkReply):
try:
response_data = self.handle_response(reply)
parsed_response = CompletedRotationScan.model_validate_json(response_data)
self.standard_scan_completed.emit(parsed_response)
except Exception as e:
print(e)
self.http_error.emit(str(e))
@Slot(RotationScanRequest)
def standard_scan(self, r: RotationScanRequest):
self.run_number_incremented.emit()
self.generic_post("scan/rotation", r.model_dump_json())
request = QNetworkRequest(QUrl(f"{self.__base_url}/scan/rotation/result"))
request = QNetworkRequest(QUrl(f"{self.__base_url}/scan/rotation"))
request.setRawHeader(b"Authorization", f"Bearer {self.__token}".encode("utf-8"))
request.setRawHeader(b"Content-Type", b"application/json")
body = r.model_dump_json()
reply = self.__net_manager.post(request, QByteArray(body.encode("utf-8")))
if r.file_prefix is not None:
reply.finished.connect(lambda: self.standard_scan_completed.emit(r.file_prefix))
reply.finished.connect(lambda: self.handle_rotation_scan_response(reply))
def handle_raster_scan_response(self, reply: QNetworkReply):
try:
@@ -252,10 +259,10 @@ class DAQWorker(QObject):
@Slot()
def load_spreadsheet(self):
if self.__base_url is None:
print(f"GET /tell/spreadsheet")
print(f"GET /sample/spreadsheet")
return
request = QNetworkRequest(QUrl(f"{self.__base_url}/tell/spreadsheet"))
request = QNetworkRequest(QUrl(f"{self.__base_url}/sample/spreadsheet"))
request.setRawHeader(b"Authorization", f"Bearer {self.__token}".encode("utf-8"))
reply = self.__net_manager.get(request)
reply.finished.connect(lambda: self.handle_spreadsheet_response(reply))
@@ -318,12 +325,20 @@ class DAQWorker(QObject):
@Slot()
def unmount(self):
self.generic_post("tell/unmount")
self.generic_post("sample/unmount")
@Slot(SampleShortInfo)
def mount(self, s: SampleShortInfo):
self.generic_post(f"tell/mount?dbid={s.db_id}")
self.generic_post(f"sample/mount?dbid={s.db_id}")
@Slot(SampleShortInfo)
def sample_manual(self, s: SampleShortInfo):
self.generic_post(f"sample/manual", s.model_dump_json())
@Slot()
def sample_clear(self):
self.generic_post("sample/clear")
@Slot()
def cancel(self):
self.generic_post("scan/cancel")
self.generic_post("scan/cancel")