GUI/DAQ: Integrate sample mounting logic and improve file path management
- Added `SampleMountLogic` for handling sample-related updates.
- Extended file path handling with additional macros (`{sample}`, `{sample_id}`, `{prefix}`).
- Updated `beam size` limits in GUI.
- Modified DAQ flux computation using BPM values.
- Enhanced `SampleShortInfo` model with `aaredb_params`.
This commit is contained in:
@@ -8,7 +8,7 @@ dependencies = [
|
||||
"pydantic==2.11.4",
|
||||
"numpy==2.2.5",
|
||||
"jfjoch_client==1.0.0rc51",
|
||||
"aareDB==0.1.1a8"
|
||||
"aareDB==0.1.1a9"
|
||||
]
|
||||
|
||||
[lint]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from enum import Enum
|
||||
from typing import Annotated, Literal, Tuple, List, Optional
|
||||
|
||||
from aareDBclient.models.data_collection_parameters import DataCollectionParameters
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from aaredaqlib.coordinate import Coordinate
|
||||
@@ -44,6 +45,7 @@ class SampleShortInfo(BaseModel):
|
||||
puck_name: str
|
||||
dewar_name: str
|
||||
sample_name: str
|
||||
aaredb_params: Optional[DataCollectionParameters] = None
|
||||
user: str = ""
|
||||
pin: Annotated[int, Field(ge=1, le=16)]
|
||||
location: DewarAddress | None = None
|
||||
|
||||
@@ -92,7 +92,8 @@ class AareWrapper:
|
||||
location=dewar_address,
|
||||
priority=1.0 if s.priority is None else s.priority,
|
||||
comment=s.comments,
|
||||
mount_count=s.mount_count or 0
|
||||
mount_count=s.mount_count or 0,
|
||||
aaredb_params=s.data_collection_parameters
|
||||
)
|
||||
)
|
||||
return SampleShortInfoList(s=ret)
|
||||
|
||||
@@ -795,7 +795,7 @@ class AareDAQ:
|
||||
light=self.light,
|
||||
cryojet_K=self.__devs.cryojet_temp,
|
||||
shutter_open=self.__devs.shutter,
|
||||
flux_ph_s=3.0e12,
|
||||
flux_ph_s=self.__devs.flux,
|
||||
sample_camera=self.__devs.samcam_settings,
|
||||
name=self.__bl,
|
||||
transmission=self.__devs.transmission.get(),
|
||||
|
||||
@@ -48,6 +48,8 @@ class BeamlineDevices:
|
||||
|
||||
self.__collimator = PV(f"{BEAMLINE}-ES-COL:TRY1")
|
||||
|
||||
self.__bpm = PV(f"{BEAMLINE}-OP-XBPM1:SumAll:MeanValue_RBV")
|
||||
|
||||
self.aerotech = aerotech.Abr(beamline)
|
||||
|
||||
self.aerotech.reload_programs()
|
||||
@@ -263,3 +265,9 @@ class BeamlineDevices:
|
||||
def samcam_settings(self, settings: SampleCameraSettings):
|
||||
print(settings)
|
||||
self.sample_cam.setup(settings.gain, settings.exposure)
|
||||
|
||||
@property
|
||||
def flux(self) -> float:
|
||||
# Very approximate value - to be changed
|
||||
# 2 nA -> 4e11 ph/s
|
||||
return self.__bpm.value / 2.0 * 4e11
|
||||
@@ -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.sample_mount_logic import SampleMountLogic
|
||||
from aaregui.threads.camera_thread import SampleCameraThread
|
||||
from aaregui.threads.daq_worker import DAQWorker
|
||||
from aaregui.threads.jfjoch_viewer import JFJochDBusClient
|
||||
@@ -111,6 +112,8 @@ class MainWindow(QMainWindow):
|
||||
self.tell_samples_dock.setAllowedAreas(Qt.DockWidgetArea.BottomDockWidgetArea)
|
||||
self.addDockWidget(Qt.DockWidgetArea.BottomDockWidgetArea, self.tell_samples_dock)
|
||||
|
||||
self.sample_logic = SampleMountLogic()
|
||||
|
||||
self.job_list_dock = QDockWidget("Automation list", self)
|
||||
self.job_list_dock.setWidget(self.job_list_panel)
|
||||
self.job_list_dock.setAllowedAreas(Qt.DockWidgetArea.BottomDockWidgetArea)
|
||||
@@ -126,20 +129,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.update.connect(self.beamline.omega_panel.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.smargon_panel.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.beam_size.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.beam_center.update_daq_status)
|
||||
self.daq.update.connect(self.data_collection.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.illumination_panel.update_daq_status)
|
||||
self.daq.update.connect(self.raster.update_daq_status)
|
||||
self.daq.update.connect(self.camera_image.update_daq_status)
|
||||
self.daq.update.connect(self.tell_samples.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.abr_tweak.update_daq_status)
|
||||
self.daq.update.connect(self.status_bar.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.samcam.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.zoom_panel.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.beam_mark.update_daq_status)
|
||||
|
||||
self.daq.raster_scan_completed.connect(self.raster.grid_scan_completed)
|
||||
|
||||
@@ -218,6 +207,24 @@ class MainWindow(QMainWindow):
|
||||
self.raster.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)
|
||||
|
||||
self.daq.update.connect(self.beamline.omega_panel.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.smargon_panel.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.beam_size.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.beam_center.update_daq_status)
|
||||
self.daq.update.connect(self.data_collection.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.illumination_panel.update_daq_status)
|
||||
self.daq.update.connect(self.raster.update_daq_status)
|
||||
self.daq.update.connect(self.camera_image.update_daq_status)
|
||||
self.daq.update.connect(self.tell_samples.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.abr_tweak.update_daq_status)
|
||||
self.daq.update.connect(self.status_bar.update_daq_status)
|
||||
self.daq.update.connect(self.beamline.samcam.update_daq_status)
|
||||
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)
|
||||
|
||||
def create_menu_bar(self):
|
||||
"""Create a menu bar with File->Quit and Help->About."""
|
||||
# Main menu bar
|
||||
|
||||
@@ -16,10 +16,10 @@ class BeamSizeWidget(QWidget):
|
||||
|
||||
grid_layout.addWidget(TitleLabel("Beam size", self), 0, 0, 1, 5)
|
||||
|
||||
self.x = NumberLineEdit(1, 40.0, 10, parent=self)
|
||||
self.x = NumberLineEdit(1, 400.0, 10, parent=self)
|
||||
self.x.newValue.connect(self.beam_size_edited)
|
||||
|
||||
self.y = NumberLineEdit(1, 40.0, 10, parent=self)
|
||||
self.y = NumberLineEdit(1, 400.0, 10, parent=self)
|
||||
self.y.newValue.connect(self.beam_size_edited)
|
||||
|
||||
grid_layout.addWidget(QLabel("x:"), 1, 0)
|
||||
|
||||
@@ -69,4 +69,3 @@ class DataCollectionSettings(QFrame):
|
||||
def update_daq_status(self, s: DAQStatusModel):
|
||||
self.raster.update_daq_status(s)
|
||||
self.screening.update_daq_status(s)
|
||||
self.file_path_panel.update_daq_status(s)
|
||||
|
||||
@@ -4,7 +4,7 @@ from datetime import datetime
|
||||
from PySide6.QtCore import Signal, Slot, Qt
|
||||
from PySide6.QtWidgets import QWidget, QGridLayout, QLabel, QLineEdit, QSpinBox, QCheckBox
|
||||
|
||||
from aaredaqlib.models import DAQStatusModel
|
||||
from aaredaqlib.models import SampleShortInfo
|
||||
from aaregui.widgets.title_label import TitleLabel
|
||||
|
||||
|
||||
@@ -34,12 +34,25 @@ class FilePathPanel(QWidget):
|
||||
grid_layout.addWidget(QLabel("Directory", parent=self), 2, 0)
|
||||
self.directory_edit = QLineEdit("{date}/{puck}/{pos}", parent=self)
|
||||
self.directory_edit.setStyleSheet("background-color: rgb(255, 255, 255);")
|
||||
self.directory_edit.setToolTip("Provide subdirectory for your files, you can use \"{date}\" as macro for date.")
|
||||
self.directory_edit.setToolTip("Provide subdirectory for your files. The following macros are allowed: <br/>"
|
||||
"<b>{date}</b> - date in format yyyymmdd <br/>"
|
||||
"<b>{puck}</b> - puck name <br/>"
|
||||
"<b>{pos}</b> - pin position in puck <br/>"
|
||||
"<b>{sample}</b> - sample name <br/>"
|
||||
"<b>{sample_id}</b> - sample id <br/>"
|
||||
"<b>{prefix}</b> - file prefix value")
|
||||
grid_layout.addWidget(self.directory_edit, 2, 1)
|
||||
|
||||
grid_layout.addWidget(QLabel("File prefix", parent=self), 3, 0)
|
||||
self.file_prefix_edit = QLineEdit("{sample}", parent=self)
|
||||
self.file_prefix_edit.setStyleSheet("background-color: rgb(255, 255, 255);")
|
||||
self.file_prefix_edit.setToolTip("Provide file prefix for your files. The following macros are allowed: <br/>"
|
||||
"<b>{date}</b> - date in format yyyymmdd <br/>"
|
||||
"<b>{puck}</b> - puck name <br/>"
|
||||
"<b>{pos}</b> - pin position in puck <br/>"
|
||||
"<b>{sample}</b> - sample name <br/>"
|
||||
"<b>{sample_id}</b> - sample id")
|
||||
|
||||
grid_layout.addWidget(self.file_prefix_edit, 3, 1)
|
||||
|
||||
grid_layout.addWidget(QLabel("Run number", parent=self), 4, 0)
|
||||
@@ -72,6 +85,8 @@ class FilePathPanel(QWidget):
|
||||
file_prefix = self.file_prefix_edit.text()
|
||||
run_number = self.run_number_edit.value()
|
||||
|
||||
dir_name = dir_name.replace('{prefix}', file_prefix)
|
||||
|
||||
if dir_name == "":
|
||||
self.__filename = ""
|
||||
elif dir_name[-1] == "/":
|
||||
@@ -120,22 +135,21 @@ class FilePathPanel(QWidget):
|
||||
def filename(self) -> str:
|
||||
return self.__filename
|
||||
|
||||
@Slot(DAQStatusModel)
|
||||
def update_daq_status(self, status: DAQStatusModel):
|
||||
if status.sample is None:
|
||||
@Slot(SampleShortInfo)
|
||||
def update_sample(self, sample: SampleShortInfo):
|
||||
if sample is None:
|
||||
self.__sample_id = -1
|
||||
self.__sample_name = "sample"
|
||||
self.__dewar_pos = "None"
|
||||
self.__puck_name = "Manual"
|
||||
self.__puck_pos = 99
|
||||
else:
|
||||
self.__sample_name = status.sample.sample_name
|
||||
self.__dewar_pos = status.sample.loc_str()
|
||||
self.__puck_name = status.sample.puck_name
|
||||
self.__puck_pos = status.sample.pin
|
||||
self.update_filename()
|
||||
self.__sample_name = sample.sample_name
|
||||
self.__dewar_pos = sample.loc_str()
|
||||
self.__puck_name = sample.puck_name
|
||||
self.__puck_pos = sample.pin
|
||||
self.run_number_edit.setValue(1)
|
||||
if sample.aaredb_params is not None and sample.aaredb_params.directory is not None:
|
||||
self.directory_edit.setText(sample.aaredb_params.directory)
|
||||
|
||||
sample_id_old = self.__sample_id
|
||||
self.__sample_id = status.sample.db_id
|
||||
if self.__sample_id != sample_id_old:
|
||||
self.run_number_edit.setValue(1)
|
||||
self.update_filename()
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
from PySide6.QtCore import QObject, Slot, Signal
|
||||
|
||||
from aaredaqlib.models import DAQStatusModel, SampleShortInfo
|
||||
|
||||
|
||||
class SampleMountLogic(QObject):
|
||||
sample_changed = Signal(SampleShortInfo)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.__sample = None
|
||||
|
||||
@Slot(DAQStatusModel)
|
||||
def update_daq_status(self, s: DAQStatusModel):
|
||||
if s.sample != self.__sample:
|
||||
self.sample_changed.emit(s.sample)
|
||||
|
||||
self.__sample = s.sample
|
||||
Reference in New Issue
Block a user