diff --git a/common/src/aaredaqlib/models.py b/common/src/aaredaqlib/models.py index d87949f6..5a1861d0 100644 --- a/common/src/aaredaqlib/models.py +++ b/common/src/aaredaqlib/models.py @@ -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) diff --git a/daq/src/aaredaq/config.py b/daq/src/aaredaq/config.py index 355b6b2d..93dbb70b 100644 --- a/daq/src/aaredaq/config.py +++ b/daq/src/aaredaq/config.py @@ -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) diff --git a/daq/src/aaredaq/daq.py b/daq/src/aaredaq/daq.py index 30802b51..4f13a210 100644 --- a/daq/src/aaredaq/daq.py +++ b/daq/src/aaredaq/daq.py @@ -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") diff --git a/daq/src/aaredaq/server.py b/daq/src/aaredaq/server.py index 7f773484..5b1f84cb 100644 --- a/daq/src/aaredaq/server.py +++ b/daq/src/aaredaq/server.py @@ -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)) diff --git a/gui/src/aaregui/main_window.py b/gui/src/aaregui/main_window.py index 16f4aac4..47fdae4f 100644 --- a/gui/src/aaregui/main_window.py +++ b/gui/src/aaregui/main_window.py @@ -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: diff --git a/gui/src/aaregui/panels/beam_center_panel.py b/gui/src/aaregui/panels/beam_center_panel.py index a3506c91..843d61b7 100644 --- a/gui/src/aaregui/panels/beam_center_panel.py +++ b/gui/src/aaregui/panels/beam_center_panel.py @@ -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) diff --git a/gui/src/aaregui/panels/beam_mark_panel.py b/gui/src/aaregui/panels/beam_mark_panel.py new file mode 100644 index 00000000..ef8b47bb --- /dev/null +++ b/gui/src/aaregui/panels/beam_mark_panel.py @@ -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() diff --git a/gui/src/aaregui/panels/beamline_controls.py b/gui/src/aaregui/panels/beamline_controls.py index 146b0542..6bd50b7f 100644 --- a/gui/src/aaregui/panels/beamline_controls.py +++ b/gui/src/aaregui/panels/beamline_controls.py @@ -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()