From d30729f65530a8fba0c0d34645dd496832b746a4 Mon Sep 17 00:00:00 2001 From: appleb_m Date: Thu, 27 Nov 2025 12:20:09 +0100 Subject: [PATCH] DAQ/AAREDB: update how raster messages are sent to the db - now include COM, max_iamge number, beam_size and beamLocation. --- common/pyproject.toml | 2 +- common/src/aaredaqlib/find_xtal.py | 8 +++++--- common/src/aaredaqlib/models.py | 25 +++++++++++++++---------- daq/pyproject.toml | 4 ++-- daq/src/aaredaq/aaredb.py | 26 +++++++++++++++++--------- daq/src/aaredaq/daq.py | 2 +- gui/pyproject.toml | 4 ++-- 7 files changed, 43 insertions(+), 28 deletions(-) diff --git a/common/pyproject.toml b/common/pyproject.toml index 039d1459..f1c9d78b 100644 --- a/common/pyproject.toml +++ b/common/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "aaredaqlib" -version = "0.2.63" +version = "0.2.64" description = "Libraries shared between AareDAQ and AareGUI" readme = "README.md" requires-python = ">=3.11" diff --git a/common/src/aaredaqlib/find_xtal.py b/common/src/aaredaqlib/find_xtal.py index 7efc468c..01c178fb 100644 --- a/common/src/aaredaqlib/find_xtal.py +++ b/common/src/aaredaqlib/find_xtal.py @@ -42,7 +42,7 @@ def identify_crystal_raster(result, r: RasterGridRequest) -> CenterOfMassModel | logger.debug(f"Maximum spots_low_res value: {max_image.spots_low_res}") logger.debug(f"Maximum image found at grid coordiantes {max_image.nx}, {max_image.ny}") logger.debug(f"Maximum image found at umL {max_image.nx * r.grid_size_mm.x}, {max_image.ny * r.grid_size_mm.y}") - com = CenterOfMassModel(n_x=max_image.n_x, n_y=max_image.n_y) + com = CenterOfMassModel(n_x=max_image.n_x, n_y=max_image.n_y, max_image=max_image.number) com_mm = com.get_com_mm(r) grid_mm_x = com_mm.x grid_mm_y = com_mm.y @@ -278,7 +278,8 @@ def get_com_image_number(com, images): for image in images: if image.nx == round(com[0]) and image.ny == round(com[1]): logger.info(f"com found for image: {image.number}") - return + return image.number + return None @@ -287,7 +288,8 @@ def raster_centre_of_mass(result_array, r:RasterGridRequest) -> CenterOfMassMode com = ndimage.center_of_mass(result_array) if com or not np.isnan(com[0]) or not np.isnan(com[1]): logger.info(f"Center of mass: {com}") - return CenterOfMassModel(n_x=com[0], n_y=com[1]) + max_image = get_com_image_number(com, result_array.images) + return CenterOfMassModel(n_x=com[0], n_y=com[1], max_image=max_image) else: logger.warning("No valid center of mass found") return None diff --git a/common/src/aaredaqlib/models.py b/common/src/aaredaqlib/models.py index f77e9162..486ad7c2 100644 --- a/common/src/aaredaqlib/models.py +++ b/common/src/aaredaqlib/models.py @@ -4,6 +4,7 @@ from enum import Enum from typing import Annotated, Literal, Tuple, List, Optional import numpy as np + from pydantic import BaseModel, Field, field_validator, AfterValidator from aaredaqlib.coordinate import Coordinate, positive_coords @@ -781,18 +782,10 @@ class SimpleScanParameters(BaseModel): d_vis: float | None = None d_tar: float | None = None -class RasterPayloadModel(BaseModel): - request: RasterGridRequest - result: ScanResult - sample_id: int - attach_image: bool = True - center_pxl: Coordinate | None - start_pxl: Coordinate - cell_size_pxl: Annotated[Coordinate, AfterValidator(positive_coords)] - class CenterOfMassModel(BaseModel): n_x: float n_y: float + max_image: int | None = None @classmethod def model_validate_maybe(cls, n_x: float, n_y: float) -> "CenterOfMassModel | None": @@ -812,4 +805,16 @@ class CenterOfMassModel(BaseModel): def com_nan_check(self): # True if both values are finite (not NaN) - return not (np.isnan(self.n_x) or np.isnan(self.n_y)) \ No newline at end of file + return not (np.isnan(self.n_x) or np.isnan(self.n_y)) + +class RasterPayloadModel(BaseModel): + request: RasterGridRequest + result: ScanResult + sample_id: int + attach_image: bool = True + centre_of_mass: CenterOfMassModel | None = None + center_pxl: Coordinate | None + start_pxl: Coordinate + cell_size_pxl: Annotated[Coordinate, AfterValidator(positive_coords)] + beam_mark_pxl: tuple[float, float] + beam_size_mm: Annotated[Coordinate, AfterValidator(positive_coords)] \ No newline at end of file diff --git a/daq/pyproject.toml b/daq/pyproject.toml index 2ca465c8..1b8294ae 100644 --- a/daq/pyproject.toml +++ b/daq/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "aaredaq" -version = "0.2.63" +version = "0.2.64" description = "AareDAQ data acquisition server" readme = "README.md" requires-python = ">=3.11" @@ -18,7 +18,7 @@ dependencies = [ "python_multipart==0.0.20", "websocket-client==1.8.0", "sseclient-py==1.8.0", - "aaredaqlib==0.2.63", + "aaredaqlib==0.2.64", ] [lint] diff --git a/daq/src/aaredaq/aaredb.py b/daq/src/aaredaq/aaredb.py index 7e8baf25..f208dd8e 100644 --- a/daq/src/aaredaq/aaredb.py +++ b/daq/src/aaredaq/aaredb.py @@ -341,12 +341,13 @@ class AareWrapper: print(e) def ingest_gridscan(self, sample: Optional[SampleShortInfo], raster_result: ScanResult, - raster_request: RasterGridRequest, geom: SampleGeometryModel, com: Optional[CenterOfMassModel]): + raster_request: RasterGridRequest, geom: SampleGeometryModel, + com: Optional[CenterOfMassModel], beam_mark_pxl:tuple[float,float]): if sample is None: return - payload = self.format_gridscan_payload(sample, raster_result, raster_request, geom, com).model_dump() + payload = self.format_gridscan_payload(sample, raster_result, raster_request, geom, com, beam_mark_pxl).model_dump() if payload is None: return @@ -366,15 +367,10 @@ class AareWrapper: def format_gridscan_payload(self, sample: Optional[SampleShortInfo], raster_result:ScanResult, raster_request:RasterGridRequest, geom:SampleGeometryModel, - com: Optional[CenterOfMassModel]) -> RasterPayloadModel|None: + com: Optional[CenterOfMassModel], beam_mark_pxl:tuple[float,float]) -> RasterPayloadModel|None: try: - if com: - center_pxl = com.get_com_pxl(raster_request, geom) - else: - center_pxl = None - cell_size_pxl = Coordinate(x=raster_request.grid_size_mm.x/geom.pixel_in_mm, y=raster_request.grid_size_mm.y/geom.pixel_in_mm) @@ -382,16 +378,28 @@ class AareWrapper: beam_loc = geom.smargon.sh_mm else: beam_loc = raster_request.smargon_top_left.sh_mm + start_pxl = geom.smargon_to_picture(beam_loc) + if com: + com_grid_pxl = com.get_com_pxl(raster_request, geom) + x = start_pxl.x + com_grid_pxl.x + y = start_pxl.y + com_grid_pxl.y + center_pxl = Coordinate(x=x,y=y) + else: + center_pxl = None + payload = RasterPayloadModel( request = raster_request, result = raster_result, sample_id = sample.db_id, attach_image = True, + centre_of_mass = com, start_pxl = start_pxl, center_pxl = center_pxl, - cell_size_pxl = cell_size_pxl + cell_size_pxl = cell_size_pxl, + beam_mark_pxl = beam_mark_pxl, + beam_size_mm = geom.beam_size_mm ) return payload diff --git a/daq/src/aaredaq/daq.py b/daq/src/aaredaq/daq.py index 1b9e515e..d8b2598e 100644 --- a/daq/src/aaredaq/daq.py +++ b/daq/src/aaredaq/daq.py @@ -599,7 +599,7 @@ class AareDAQ: try: self.__aare.ingest_gridscan(sample = self.sample, raster_result =result, raster_request = r, geom = self.sample_geometry, - com = com) + com = com, beam_mark_pxl=self.__cfg.get_beam_mark(self.zoom)) except Exception as e: logger.error(f"Exception ingesting grid scan: {e}") self.__devs.reflector_up = False diff --git a/gui/pyproject.toml b/gui/pyproject.toml index 8d9a3a7f..2f96c26d 100644 --- a/gui/pyproject.toml +++ b/gui/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "aaregui" -version = "0.2.63" +version = "0.2.64" description = "Beamline control GUI" readme = "README.md" requires-python = ">=3.11" @@ -9,7 +9,7 @@ dependencies = [ "pyzmq==26.4.0", "opencv-python-headless==4.11.0.86", "PySide6==6.9.0", - "aaredaqlib==0.2.63" + "aaredaqlib==0.2.64" ] [lint]