From a10d0a9f9539bd7be6ea822da825e4aa5eb9eafa Mon Sep 17 00:00:00 2001 From: David Perl Date: Fri, 21 Aug 2026 12:26:59 +0200 Subject: [PATCH] feat: use beam centre model for diffractiongeometry --- .../default/beamline_dispatch.py | 5 +- src/aare/beamline_dispatch/protocols.py | 4 +- src/aare/daq/daq.py | 68 ++++++++----------- src/aare/daq/devices.py | 7 +- src/aare/daq/server.py | 2 +- 5 files changed, 39 insertions(+), 47 deletions(-) diff --git a/src/aare/beamline_dispatch/default/beamline_dispatch.py b/src/aare/beamline_dispatch/default/beamline_dispatch.py index 907aaf82..6b7112cd 100644 --- a/src/aare/beamline_dispatch/default/beamline_dispatch.py +++ b/src/aare/beamline_dispatch/default/beamline_dispatch.py @@ -3,6 +3,7 @@ import os from importlib.resources import files from aarecommon.config.beamline import MXBeamline +from aarecommon.math.beam_center import BeamCenterFromDetectorStage from aarecommon.models.beam_centre import BeamCentre from aare.beamline_dispatch.protocols import AuthDispatch, BeamlineDispatch, Geometry @@ -26,8 +27,8 @@ class DefaultGeometry(Geometry): self._beamline = beamline @property - def beam_centre_model(self) -> BeamCentre: - return self._model + def beam_centre_model(self) -> BeamCenterFromDetectorStage: + return self._model.model class DefaultDispatch(BeamlineDispatch): diff --git a/src/aare/beamline_dispatch/protocols.py b/src/aare/beamline_dispatch/protocols.py index 4039009f..e6f2e340 100644 --- a/src/aare/beamline_dispatch/protocols.py +++ b/src/aare/beamline_dispatch/protocols.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from typing import Any -from aarecommon.models.beam_centre import BeamCentre +from aarecommon.math.beam_center import BeamCenterFromDetectorStage class AuthDispatch(ABC): @@ -33,7 +33,7 @@ class BecMacros(ABC): class Geometry(ABC): @property @abstractmethod - def beam_centre_model(self) -> BeamCentre: ... + def beam_centre_model(self) -> BeamCenterFromDetectorStage: ... class BeamlineDispatch(ABC): diff --git a/src/aare/daq/daq.py b/src/aare/daq/daq.py index 24301e54..435ef924 100644 --- a/src/aare/daq/daq.py +++ b/src/aare/daq/daq.py @@ -67,6 +67,7 @@ from aarecommon.models.rotation_scan import CompletedRotationScan, RotationScanR from aarecommon.models.tell import TellPhaseEnum, TellStateModel from aareDB import SampleEventType +from aare.beamline_dispatch.protocols import BeamlineDispatch from aare.daq import workflows from aare.daq.aaredb import AareWrapper from aare.daq.config import ABR_POS_MOUNT, BeamlineConfig, BeamlineStateEnum @@ -270,8 +271,9 @@ class AareDAQ: AUTO_RASTER_MIN_CELL_SIZE_MM = 0.005 AUTO_RASTER_SKIP_IF_EXCEED_MAX_IMAGE_THRESHOLD = True - def __init__(self, cfg: BeamlineConfig, bl: MXBeamline): + def __init__(self, cfg: BeamlineConfig, bl: MXBeamline, dispatch: BeamlineDispatch): self.last_time = 0.0 + self._dispatch = dispatch self._cfg = cfg self._devs = BeamlineDevices(bl) self._mlbox = MlBox(bl) @@ -3151,46 +3153,30 @@ class AareDAQ: @property def diffraction_geometry(self) -> DiffractionGeometry: - try: - metadata = self._cached_detector_metadata() - width = int(metadata.get("detector_width", 1)) - height = int(metadata.get("detector_height", 1)) - pixel_size_mm = float(metadata.get("pixel_size_mm", 0.15)) - detector_description = str(metadata.get("detector_description", "unavailable")) - detector_serial_number = str(metadata.get("detector_serial_number", "unavailable")) - energy = self._devs.energy_kev - dtz = self._devs.dtz - beam_center = self._cfg.beam_center - return DiffractionGeometry( - energy_keV=energy, - dtz_mm=dtz, - detector_size_pxl=(width, height), - pixel_size_mm=pixel_size_mm, - beam_center_pxl=beam_center, - detector_description=detector_description, - detector_serial_number=detector_serial_number, - poni_rot1_rad=-0.001396263, - poni_rot2_rad=-0.003839724, - ) - except Exception as e: - logger.warning( - f"Falling back to default diffraction geometry because cached detector metadata is unavailable: {e}", - exc_info=True, - ) - energy = self._devs.energy_kev - dtz = self._devs.dtz - beam_center = self._cfg.beam_center - return DiffractionGeometry( - energy_keV=energy, - dtz_mm=dtz, - detector_size_pxl=(1, 1), - pixel_size_mm=0.15, - beam_center_pxl=beam_center, - detector_description="unavailable", - detector_serial_number="unavailable", - poni_rot1_rad=-0.001396263, - poni_rot2_rad=-0.003839724, - ) + metadata = self._cached_detector_metadata() + width = int(metadata.get("detector_width", 1)) + height = int(metadata.get("detector_height", 1)) + pixel_size_mm = float(metadata.get("pixel_size_mm", 0.15)) + detector_description = str(metadata.get("detector_description", "unavailable")) + detector_serial_number = str(metadata.get("detector_serial_number", "unavailable")) + energy = self._devs.energy_kev + dtz = self._devs.dtz + beam_center_x, beam_center_y = self._dispatch.geo.beam_centre_model.predict( + dtz, self._devs.dty + ) + beam_center_x, beam_center_y = float(beam_center_x[0]), float(beam_center_y[0]) + + return DiffractionGeometry( + energy_keV=energy, + dtz_mm=dtz, + detector_size_pxl=(width, height), + pixel_size_mm=pixel_size_mm, + beam_center_pxl=(beam_center_x, beam_center_y), + detector_description=detector_description, + detector_serial_number=detector_serial_number, + poni_rot1_rad=-0.001396263, + poni_rot2_rad=-0.003839724, + ) @property def beamline_status(self) -> BeamlineStatus: diff --git a/src/aare/daq/devices.py b/src/aare/daq/devices.py index 16a46b99..4a16fa8b 100644 --- a/src/aare/daq/devices.py +++ b/src/aare/daq/devices.py @@ -42,6 +42,7 @@ class BeamlineDevices: # faster to define the dtz object here than in functions and then use self._dtz = self.bec_worker.dev.det_z + self._dty = self.bec_worker.dev.det_y self.dtz_mod = cfg_get("daq.detector_distance_limit_modifier", 1.0) # TODO convert epics pvs to BEC self._sample_cam = epicsAD(f"{BEAMLINE}-ES-MS:") @@ -267,7 +268,11 @@ class BeamlineDevices: # Detector Z @property def dtz(self) -> float: - return self._dtz.read()["det_z"]["value"] + return self._dtz.user_setpoint.get() + + @property + def dty(self) -> float: + return self._dty.user_setpoint.get() @dtz.setter def dtz(self, value: float): diff --git a/src/aare/daq/server.py b/src/aare/daq/server.py index 8cf15fda..63a82eae 100644 --- a/src/aare/daq/server.py +++ b/src/aare/daq/server.py @@ -108,7 +108,7 @@ async def lifespan(application: FastAPI): # ── Core objects (Redis, EPICS PVs, BEC, TELL, JFJoch, etc.) ── bl = mx_beamline() cfg = BeamlineConfig(bl) - daq = AareDAQ(cfg, bl) + daq = AareDAQ(cfg, bl, bl_dispatch) cfg.state = daq.read_current_state_from_bec() try: