Merge branch 'daq_raster_predicition'

# Conflicts:
#	daq/src/aaredaq/daq.py
#	gui/src/aaregui/panels/rotation_data_collection.py
This commit is contained in:
leonarski_f committed 2025-10-20 12:48:47 +02:00
commit 0243d5c8b9
11 files changed
+468 -404

No files matched your search

+3 -2
View File
@@ -68,8 +68,8 @@ class MainWindow(QMainWindow):
beam_center_pxl=(750, 750),
detector_description="PILATUS 4",
detector_serial_number="1",
poni_rot1_rad=0,
poni_rot2_rad=0
poni_rot1_rad=-0.001396263,
poni_rot2_rad=-0.003839724
)
geom = SampleGeometryModel(beam_location_pxl=Coordinate(x=1000,y=1000),
@@ -251,6 +251,7 @@ class MainWindow(QMainWindow):
self.raster.grid_scan_auto.connect(self.daq.raster_scan_auto)
self.data_collection.screening.rotation_scan.connect(self.daq.standard_scan)
self.data_collection.simple.rotation_scan.connect(self.daq.standard_scan)
self.data_collection.simple.parameters_changed.connect(self.daq.smart_params)
self.raster.grid_scan_size_changed.connect(self.data_collection.raster.grid_scan_size_change)
self.status_bar.set_pgroup.connect(self.daq.set_pgroup)
@@ -123,7 +123,7 @@ class RotationDataCollectionPanel(ScanSettingsPanel):
@Slot()
def run_measurement(self):
r = RotationScanRequest(
file_prefix=str(add_data_to_path(self._filename)), #self._filename,
file_prefix=str(add_data_to_path(self._filename)),
start_omega_deg=self.start_angle.value,
steps=self.image_number(),
incr_omega_deg=self.image_angle.value,
+108 -80
View File
@@ -3,19 +3,22 @@ import math
from PySide6.QtCore import Slot, Qt, Signal
from PySide6.QtWidgets import QWidget, QGridLayout, QLabel, QFrame, QPushButton, QSpacerItem, QSizePolicy
from aaredaqlib.models import DAQStatusModel
from aaredaqlib.models import DAQStatusModel, SimpleScanParameters
from aaredaqlib.rotation_scan import RotationScanRequest
from aaregui.panels.rotation_data_collection import add_data_to_path
from aaregui.widgets.number_line_edit import NumberLineEdit
class SimpleRotationSettingsPanel(QWidget):
rotation_scan = Signal(RotationScanRequest)
viewer_track_online = Signal()
parameters_changed = Signal(SimpleScanParameters)
def __init__(self, parent=None):
super().__init__(parent)
self.n_images = 1
self.xtal_size_dose_rate_MGy_s = None
self.xtal_x = None
self.xtal_y = None
@@ -24,14 +27,12 @@ class SimpleRotationSettingsPanel(QWidget):
self.dose_rate_MGy_s = None
self._filename = ""
self.dtz = 120
self.n_images = None
self.transmission = 1.0
self.image_time_s = None
self.image_angle = 0.2
self.image_time_s = 0.1
self.__d = None
self._temperature = 100
self.__omega = 0
self._wilson_b = 0
self._wilson_b = None
self.parameters = SimpleScanParameters()
self._layout = QGridLayout(self)
@@ -44,73 +45,75 @@ class SimpleRotationSettingsPanel(QWidget):
self._layout.addWidget(QLabel("Å", parent=self), 0, 4)
self.visible_res_enter.newValue.connect(self.set_visible_resolution)
# Angular range (entry)
self._layout.addWidget(QLabel("Total angle", parent=self), 1, 0)
self.angular_range_enter = NumberLineEdit(
5.0, 1000.0, decimals=3, default=210.0, parent=self
)
self._layout.addWidget(self.angular_range_enter, 1, 1, 1, 3)
self._layout.addWidget(QLabel("Start angle", parent=self), 1, 0)
self.start_angle_enter = NumberLineEdit(-720, 720.0, 0.0, decimals=3, parent=self)
self._layout.addWidget(self.start_angle_enter, 1, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 1, 4)
self.visible_res_enter.newValue.connect(self.set_visible_resolution)
# Calculated labels
self._layout.addWidget(QLabel("Target resolution", parent=self), 2, 0)
self.target_res_label = QLabel("--", parent=self)
self.target_res_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.target_res_label, 2, 1, 1, 3)
self._layout.addWidget(QLabel("Å", parent=self), 2, 4)
self._layout.addWidget(QLabel("Image angle", parent=self), 3, 0)
self.image_angle_label = QLabel("--", parent=self)
self.image_angle_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.image_angle_label, 3, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 3, 4)
self._layout.addWidget(QLabel("Image time", parent=self), 4, 0)
self.image_time_label = QLabel("--", parent=self)
self.image_time_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.image_time_label, 4, 1, 1, 3)
self._layout.addWidget(QLabel("s", parent=self), 4, 4)
self._layout.addWidget(QLabel("Transmission", parent=self), 5, 0)
self.transmission_label = QLabel("--", parent=self)
self.transmission_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.transmission_label, 5, 1, 1, 3)
self._layout.addWidget(QLabel("%", parent=self), 5, 4)
self._layout.addWidget(QLabel("Detector distance", parent=self), 6, 0)
self.dtz_label = QLabel(f"--", parent=self)
self.dtz_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.dtz_label, 6, 1, 1, 3)
self._layout.addWidget(QLabel("mm", parent=self), 6, 4)
self._layout.addWidget(QLabel("Target Dose", parent=self), 7, 0)
self.target_dose_label = QLabel(f"--", parent=self)
self.target_dose_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.target_dose_label, 7, 1, 1, 3)
self._layout.addWidget(QLabel("MGy", parent=self), 7, 4)
self._layout.addWidget(QLabel("Calculated Dose Rate", parent=self), 8, 0)
self.calculated_dose_rate_label = QLabel(f"--", parent=self)
self.calculated_dose_rate_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.calculated_dose_rate_label, 8, 1, 1, 3)
self._layout.addWidget(QLabel("MGy S^-1", parent=self), 8, 4)
self._layout.addWidget(QLabel("Temperature", parent=self), 9, 0)
self.temp_enter = NumberLineEdit(80, 330, decimals=2, default=100.0, parent=self)
self._layout.addWidget(self.temp_enter, 9, 1, 1, 3)
self._layout.addWidget(QLabel("K", parent=self), 9, 4)
self.temp_enter.newValue.connect(self.set_temperature)
self._layout.addWidget(QLabel("Start angle", parent=self), 10, 0)
self.start_angle = NumberLineEdit(-720, 720.0, 0.0, decimals=3, parent=self)
self._layout.addWidget(self.start_angle, 10, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 10, 4)
self.omega_button = QPushButton("Ω")
self.omega_button.setFixedWidth(20)
self.omega_button.clicked.connect(self.update_omega_start)
self._layout.addWidget(self.omega_button, 10, 5)
self._layout.addWidget(self.omega_button, 1, 5)
# Angular range (entry)
self._layout.addWidget(QLabel("Total angle", parent=self), 2, 0)
self.angular_range_enter = NumberLineEdit(
5.0, 1000.0, decimals=3, default=360.0, parent=self
)
self._layout.addWidget(self.angular_range_enter, 2, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 2, 4)
self.visible_res_enter.newValue.connect(self.set_total_angle)
self._layout.addWidget(QLabel("Image angle", parent=self), 3, 0)
self.image_angle_enter = NumberLineEdit(
0.001, 1.000, decimals=3, default=0.2, parent=self
)
self._layout.addWidget(self.image_angle_enter, 3, 1, 1, 3)
self._layout.addWidget(QLabel("°", parent=self), 3, 4)
self.image_angle_enter.newValue.connect(self.set_image_angle)
self._layout.addWidget(QLabel("Temperature", parent=self), 4, 0)
self.temp_enter = NumberLineEdit(80, 330, decimals=2, default=100.0, parent=self)
self._layout.addWidget(self.temp_enter, 4, 1, 1, 3)
self._layout.addWidget(QLabel("K", parent=self), 4, 4)
self.temp_enter.newValue.connect(self.set_temperature)
# Calculated labels
self._layout.addWidget(QLabel("Target resolution", parent=self), 5, 0)
self.target_res_label = QLabel("--", parent=self)
self.target_res_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.target_res_label, 5, 1, 1, 3)
self._layout.addWidget(QLabel("Å", parent=self), 5, 4)
self._layout.addWidget(QLabel("Image time", parent=self), 6, 0)
self.image_time_label = QLabel("--", parent=self)
self.image_time_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.image_time_label, 6, 1, 1, 3)
self._layout.addWidget(QLabel("s", parent=self), 6, 4)
self._layout.addWidget(QLabel("Transmission", parent=self), 7, 0)
self.transmission_label = QLabel("--", parent=self)
self.transmission_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.transmission_label, 7, 1, 1, 3)
self._layout.addWidget(QLabel("%", parent=self), 7, 4)
self._layout.addWidget(QLabel("Detector distance", parent=self), 8, 0)
self.dtz_label = QLabel(f"--", parent=self)
self.dtz_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.dtz_label, 8, 1, 1, 3)
self._layout.addWidget(QLabel("mm", parent=self), 8, 4)
self._layout.addWidget(QLabel("Target Dose", parent=self), 9, 0)
self.target_dose_label = QLabel(f"--", parent=self)
self.target_dose_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.target_dose_label, 9, 1, 1, 3)
self._layout.addWidget(QLabel("MGy", parent=self), 9, 4)
self._layout.addWidget(QLabel("Calculated Dose Rate", parent=self), 10, 0)
self.calculated_dose_rate_label = QLabel(f"--", parent=self)
self.calculated_dose_rate_label.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self._layout.addWidget(self.calculated_dose_rate_label, 10, 1, 1, 3)
self._layout.addWidget(QLabel("MGy S^-1", parent=self), 10, 4)
self._layout.addWidget(QLabel("Wilson B Factor", parent=self), 11, 0)
self.wilson_b_label = QLabel(f"--", parent=self)
@@ -178,7 +181,11 @@ class SimpleRotationSettingsPanel(QWidget):
@Slot(DAQStatusModel)
def update_daq_status(self, s: DAQStatusModel):
self.__d = s
#TODO only update best_res after raster finished otherwise ask to update. or have toggle to overwrite with user value
#TODO only take best res from flat face scan
#TODO identify flat face!!!!
best_res = s.last_best_res
self.__omega = s.geom.omega_deg
if best_res is not None:
# clamp to control limits and update field; this will also trigger recalculation
@@ -187,10 +194,10 @@ class SimpleRotationSettingsPanel(QWidget):
self.visible_res_enter.update_value(v)
self.set_visible_resolution(v)
best_b_factor = s.last_best_b_factor
self._wilson_b = s.last_best_b_factor
if best_b_factor is not None:
self.wilson_b_label.setText(f"{best_b_factor:.2f}")
if self._wilson_b is not None:
self.wilson_b_label.setText(f"{self._wilson_b:.2f}")
xtal_size = s.crystal_size
if xtal_size is not None:
@@ -211,12 +218,21 @@ class SimpleRotationSettingsPanel(QWidget):
self.wavelength_label.setText("<b>N/A</b>")
else:
self.wavelength_label.setText(f"<b>{s.diffraction.wavelength_angstrom:.3f}</b>")
self.update_calculated_labels()
@Slot(float)
def set_visible_resolution(self, v: float):
self.update_calculated_labels()
@Slot(float)
def set_total_angle(self, v: float):
self.update_calculated_labels()
@Slot(float)
def set_image_angle(self, v: float):
self.update_calculated_labels()
@Slot(float)
def set_temperature(self, v: float):
self.update_calculated_labels()
@@ -227,7 +243,7 @@ class SimpleRotationSettingsPanel(QWidget):
@Slot()
def update_omega_start(self):
self.start_angle.update_value(self.__omega)
self.start_angle_enter.update_value(self.__omega)
def update_calculated_labels(self):
if self.__d is None:
@@ -238,9 +254,12 @@ class SimpleRotationSettingsPanel(QWidget):
#TODO read resolution estiamtion from jfjoch
total_angle = self.angular_range_enter.value
d_vis = self.visible_res_enter.value
image_angle = self.image_angle_enter.value
if d_vis == 0.0:
d_vis = 1.3
d_tar = 1/(1/d_vis + 0.1)
self.target_res_label.setText(f"{d_tar:.2f}")
#self.wilson_b_label.setText("--")
Kdose = 2000 / (self.__d.diffraction.wavelength_angstrom**2)
@@ -271,10 +290,9 @@ class SimpleRotationSettingsPanel(QWidget):
total_time_s = self.target_dose_MGy / self.dose_rate_MGy_s
self.calculated_dose_label.setText(f"{self.xtal_size_dose_rate_MGy_s*total_time_s:.2f}")
self.image_angle = 0.2
self.image_angle_label.setText(f"{self.image_angle:.3f}")
self.n_images = total_angle / self.image_angle
if image_angle == 0.0:
image_angle = 0.001
self.n_images = round(total_angle / image_angle)
self.image_time_s = total_time_s / self.n_images
if self.image_time_s < 0.01:
self.transmission = self.image_time_s / 0.01
@@ -295,13 +313,23 @@ class SimpleRotationSettingsPanel(QWidget):
else:
self.dtz_label.setText(f"{self.dtz:.2f}")
self.parameters = SimpleScanParameters(
dtz=int(round(self.dtz)),
exp_time_s=self.image_time_s,
start_omega_deg=self.start_angle_enter.value,
incr_omega_deg=image_angle,
steps=self.n_images,
transmission=self.transmission
)
self.parameters_changed.emit(self.parameters)
@Slot()
def run_measurement(self):
r = RotationScanRequest(
file_prefix=self._filename,
start_omega_deg=0,#,self.start_angle.value,
file_prefix=str(add_data_to_path(self._filename)),
start_omega_deg=self.start_angle_enter.value,
steps=self.n_images,
incr_omega_deg=self.image_angle,
incr_omega_deg=self.image_angle_enter.value,
dtz=self.dtz,
transmission=self.transmission,
screening=False,
+8 -1
View File
@@ -7,7 +7,7 @@ from jfjoch_client import ScanResult, ScanResultImagesInner
from aaredaqlib.coordinate import SmargonCoordinate, Coordinate
from aaredaqlib.models import DAQStatusModel, SampleShortInfoList, SampleShortInfo, SampleCameraSettings, \
AutofocusSettings
AutofocusSettings, SimpleScanParameters
from aaredaqlib.raster_grid import RasterGridRequest, CompletedRasterGrid
from aaredaqlib.rotation_scan import RotationScanRequest, CompletedRotationScan
@@ -351,6 +351,13 @@ class DAQWorker(QObject):
reply = self.__net_manager.post(request, QByteArray(body.encode("utf-8")))
reply.finished.connect(lambda: self.handle_auto_scan_response(reply, s.db_id))
@Slot(SimpleScanParameters)
def smart_params(self, p: SimpleScanParameters):
if self.__base_url is None:
print(f"POST /scan/smart_params: {p.model_dump_json()}")
return
self.generic_post("scan/smart_params", p.model_dump_json())
@Slot(Coordinate)
def abr_tweak(self, c: Coordinate):
self.generic_post("beamline/tweak_abr_meas_pos", c.model_dump_json())