diff --git a/common/pyproject.toml b/common/pyproject.toml
index 91ee788d..22916052 100644
--- a/common/pyproject.toml
+++ b/common/pyproject.toml
@@ -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]
diff --git a/common/src/aaredaqlib/models.py b/common/src/aaredaqlib/models.py
index 6ec3874f..685b5c92 100644
--- a/common/src/aaredaqlib/models.py
+++ b/common/src/aaredaqlib/models.py
@@ -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
diff --git a/daq/src/aaredaq/aaredb.py b/daq/src/aaredaq/aaredb.py
index 4230f64a..0af75885 100644
--- a/daq/src/aaredaq/aaredb.py
+++ b/daq/src/aaredaq/aaredb.py
@@ -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)
diff --git a/daq/src/aaredaq/daq.py b/daq/src/aaredaq/daq.py
index 05859229..e2869127 100644
--- a/daq/src/aaredaq/daq.py
+++ b/daq/src/aaredaq/daq.py
@@ -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(),
diff --git a/daq/src/aaredaq/devices.py b/daq/src/aaredaq/devices.py
index 66eaf7a2..a2c31331 100644
--- a/daq/src/aaredaq/devices.py
+++ b/daq/src/aaredaq/devices.py
@@ -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
\ No newline at end of file
diff --git a/gui/src/aaregui/main_window.py b/gui/src/aaregui/main_window.py
index ebf425cc..71fd322f 100644
--- a/gui/src/aaregui/main_window.py
+++ b/gui/src/aaregui/main_window.py
@@ -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
diff --git a/gui/src/aaregui/panels/beam_size_panel.py b/gui/src/aaregui/panels/beam_size_panel.py
index 785399c7..59fd54cd 100644
--- a/gui/src/aaregui/panels/beam_size_panel.py
+++ b/gui/src/aaregui/panels/beam_size_panel.py
@@ -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)
diff --git a/gui/src/aaregui/panels/data_collection_settings.py b/gui/src/aaregui/panels/data_collection_settings.py
index 1968da6c..3a32e7d7 100644
--- a/gui/src/aaregui/panels/data_collection_settings.py
+++ b/gui/src/aaregui/panels/data_collection_settings.py
@@ -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)
diff --git a/gui/src/aaregui/panels/file_path_panel.py b/gui/src/aaregui/panels/file_path_panel.py
index e98229c8..31809a3b 100644
--- a/gui/src/aaregui/panels/file_path_panel.py
+++ b/gui/src/aaregui/panels/file_path_panel.py
@@ -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:
"
+ "{date} - date in format yyyymmdd
"
+ "{puck} - puck name
"
+ "{pos} - pin position in puck
"
+ "{sample} - sample name
"
+ "{sample_id} - sample id
"
+ "{prefix} - 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:
"
+ "{date} - date in format yyyymmdd
"
+ "{puck} - puck name
"
+ "{pos} - pin position in puck
"
+ "{sample} - sample name
"
+ "{sample_id} - 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)
\ No newline at end of file
+ self.update_filename()
diff --git a/gui/src/aaregui/scan_logic/sample_mount_logic.py b/gui/src/aaregui/scan_logic/sample_mount_logic.py
new file mode 100644
index 00000000..03ecaa88
--- /dev/null
+++ b/gui/src/aaregui/scan_logic/sample_mount_logic.py
@@ -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