DAQ: Deconvolute beam mark / beam center

This commit is contained in:
2025-06-13 11:33:39 +02:00
parent 3988c345c9
commit ca69bb0094
8 changed files with 82 additions and 31 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ class SampleShortInfoList(BaseModel):
s: List[SampleShortInfo]
class BeamCenterCoeffModel(BaseModel):
class BeamMarkCoeffModel(BaseModel):
"""
Model to calculate beam center for a given zoom level based on a quadratic approximation
For both x and y it contains tuple of coefficients a, b, c (a*zoom^2 + b*zoom + c)
+9 -9
View File
@@ -9,7 +9,7 @@ import redis_lock
from aaredaqlib.coordinate import Coordinate
from aaredaqlib.models import (
BeamlineSettingsModel,
BeamCenterCoeffModel,
BeamMarkCoeffModel,
LoopCenteringZoomModel,
def_loop_centering_zoom,
SampleShortInfo,
@@ -241,16 +241,16 @@ class BeamlineConfig:
self.__client.set(f"{self.__bl}:current_sample", sample.model_dump_json())
@property
def beam_center_coeff(self) -> BeamCenterCoeffModel:
def beam_mark_coeff(self) -> BeamMarkCoeffModel:
tmp = self.__client.get(f"{self.__bl}:beam_center_camera")
if tmp is None:
return BeamCenterCoeffModel()
return BeamMarkCoeffModel()
data_dict = json.loads(tmp)
return BeamCenterCoeffModel(**data_dict)
return BeamMarkCoeffModel(**data_dict)
@beam_center_coeff.setter
def beam_center_coeff(self, data: BeamCenterCoeffModel):
@beam_mark_coeff.setter
def beam_mark_coeff(self, data: BeamMarkCoeffModel):
self.__client.set(f"{self.__bl}:beam_center_camera", data.model_dump_json())
@property
@@ -343,14 +343,14 @@ class BeamlineConfig:
x_pxls.append(float(json.loads(v)["x"]))
y_pxls.append(float(json.loads(v)["y"]))
model = BeamCenterCoeffModel(
model = BeamMarkCoeffModel(
coeff_x=tuple(np.polyfit(zooms, x_pxls, deg=2)),
coeff_y=tuple(np.polyfit(zooms, y_pxls, deg=2)),
)
self.beam_center_coeff = model
self.beam_mark_coeff = model
def get_beam_mark(self, zoom: float) -> tuple[float, float]:
model = self.beam_center_coeff
model = self.beam_mark_coeff
x_pxl = np.polyval(model.coeff_x, zoom)
y_pxl = np.polyval(model.coeff_y, zoom)
return float(x_pxl), float(y_pxl)
+15 -8
View File
@@ -389,7 +389,7 @@ class AareDAQ:
zoom = self.__devs.zoom
abr_pos = self.__cfg.abr_meas_pos
return SampleGeometryModel(
beam_location_pxl=self.__cfg.beam_center_coeff.apply(zoom),
beam_location_pxl=self.__cfg.beam_mark_coeff.apply(zoom),
pixel_in_mm=self.__cfg.pixel_to_mm(zoom),
omega_deg=self.__devs.aerotech.omega,
smargon=self.__devs.smargon.readback,
@@ -399,11 +399,18 @@ class AareDAQ:
y=self.__devs.gmy.value - abr_pos.y,
z=self.__devs.gmz.value - abr_pos.z,
),
aerotech_meas=self.__devs.abr_pos,
detector_radius_mm = 115.0 # PILATUS4 2M / JUNGFRAU 9M
aerotech_meas=self.__devs.abr_pos
)
def get_beam_center(self):
@property
def beam_center(self) -> Tuple[float, float]:
return self.__cfg.beam_center
@beam_center.setter
def beam_center(self, val: Tuple[float, float]):
self.__cfg.beam_center = val
def get_beam_mark(self):
return self.__cfg.get_beam_mark(self.__devs.zoom)
def listen_changes(self) -> redis.client.PubSub:
@@ -603,10 +610,10 @@ class AareDAQ:
)
)
self.__rotation(
RotationScanRequest(total_omega_deg=360,
start_omega_deg=0,
total_time_sec=18))
#self.__rotation(
# RotationScanRequest(total_omega_deg=360,
# start_omega_deg=0,
# total_time_sec=18))
self.save_screenshot_db(sample.db_id, "after_dc.jpeg")
+9 -3
View File
@@ -98,19 +98,25 @@ async def save_abr_meas_pos(token: str = Depends(oauth2_scheme)):
return "OK"
@app.post("/beam_center/mark")
@app.post("/beam_mark/add")
async def mark_beam_center(x: float, y: float, token: str = Depends(oauth2_scheme)):
auth.check_jwt_staff(auth.parse_token(token))
daq.mark_beam(x, y)
return "OK"
@app.post("/beam_center/clear")
async def clear_beam_center(token: str = Depends(oauth2_scheme)):
@app.post("/beam_mark/clear")
async def clear_beam_mark(token: str = Depends(oauth2_scheme)):
auth.check_jwt_staff(auth.parse_token(token))
daq.clear_mark_beam()
return "OK"
@app.post("/beamline/beam_center")
async def beam_center(x: float, y: float, token: str = Depends(oauth2_scheme)):
auth.check_jwt_staff(auth.parse_token(token))
daq.beam_center = (x, y)
return "OK"
@app.put("/beamline/samcam")
async def samcam_settings(s: SampleCameraSettings, token: str = Depends(oauth2_scheme)):
auth.check_jwt_rw(cfg, auth.parse_token(token))
+1 -1
View File
@@ -154,7 +154,7 @@ class MainWindow(QMainWindow):
self.beamline.abr_tweak.abr_tweak.connect(self.daq.abr_tweak)
self.beamline.abr_tweak.abr_save.connect(self.daq.abr_save)
self.beamline.beam_center.beam_center_clear.connect(self.daq.beam_center_clear)
self.beamline.beam_mark.beam_mark_clear.connect(self.daq.beam_center_clear)
self.camera_image.update_beam_center.connect(self.daq.beam_center_mark)
if zmq_addr is not None:
+21 -9
View File
@@ -1,23 +1,35 @@
from PySide6.QtCore import Signal, Slot
from PySide6.QtWidgets import QWidget, QGridLayout, QPushButton
from PySide6.QtWidgets import QWidget, QGridLayout, QLabel
from aaredaqlib.models import DAQStatusModel
from aaregui.widgets.number_line_edit import NumberLineEdit
from aaregui.widgets.title_label import TitleLabel
class BeamCenterWidget(QWidget):
beam_center_clear = Signal()
beam_center = Signal(float, float)
def __init__(self, parent=None):
super().__init__(parent)
grid_layout = QGridLayout(self)
grid_layout.addWidget(TitleLabel("Beam center", self), 0, 0)
grid_layout.addWidget(TitleLabel("Beam center", self), 0, 0, 1, 5)
clear_button = QPushButton("Clear marks")
grid_layout.addWidget(clear_button, 1, 0)
clear_button.pressed.connect(self.clear_button_pressed)
self.x = NumberLineEdit(-4000, 4000, 0, parent=self)
self.y = NumberLineEdit(-4000, 4000, 0, parent=self)
@Slot()
def clear_button_pressed(self):
self.beam_center_clear.emit()
grid_layout.addWidget(QLabel("x:"), 1, 0)
grid_layout.addWidget(self.x, 1, 1)
grid_layout.addWidget(QLabel("y:"), 1, 2)
grid_layout.addWidget(self.y, 1, 3)
grid_layout.addWidget(QLabel("pxl"), 1, 4)
@Slot(DAQStatusModel)
def update_daq_status(self, s: DAQStatusModel):
self.x.update_value(s.diffraction.beam_center_x)
self.y.update_value(s.diffraction.beam_center_y)
@Slot(float)
def beam_center_edited(self, _: float):
self.beam_center.emit(self.x.value, self.y.value)
+23
View File
@@ -0,0 +1,23 @@
from PySide6.QtCore import Signal, Slot
from PySide6.QtWidgets import QWidget, QGridLayout, QPushButton
from aaregui.widgets.title_label import TitleLabel
class BeamMarkWidget(QWidget):
beam_mark_clear = Signal()
def __init__(self, parent=None):
super().__init__(parent)
grid_layout = QGridLayout(self)
grid_layout.addWidget(TitleLabel("Beam mark (image)", self), 0, 0)
clear_button = QPushButton("Clear marks")
grid_layout.addWidget(clear_button, 1, 0)
clear_button.pressed.connect(self.clear_button_pressed)
@Slot()
def clear_button_pressed(self):
self.beam_mark_clear.emit()
@@ -2,6 +2,7 @@ from PySide6.QtWidgets import QFrame, QVBoxLayout
from aaregui.panels.abr_tweak_panel import AbrTweakWidget
from aaregui.panels.beam_center_panel import BeamCenterWidget
from aaregui.panels.beam_mark_panel import BeamMarkWidget
from aaregui.panels.beamline_state_panel import BeamlineStatePanel
from aaregui.panels.illumination_panel import IlluminationPanel
from aaregui.panels.loop_centering_panel import LoopCenteringPanel
@@ -43,10 +44,12 @@ class BeamlineControls(QFrame):
self.v_layout.addWidget(self.samcam)
self.abr_tweak = AbrTweakWidget(self)
self.beam_mark = BeamMarkWidget(self)
self.beam_center = BeamCenterWidget(self)
if staff:
self.v_layout.addWidget(self.abr_tweak)
self.v_layout.addWidget(self.beam_mark)
self.v_layout.addWidget(self.beam_center)
self.v_layout.addStretch()