DAQ: bug fixes in new implementation of raster ingest, plus send COM too GUI for JFJoch viewer
Build and Publish / build (push) Failing after 26s

This commit is contained in:
appleb_m committed 2025-11-27 12:54:21 +01:00
1 parent e8b03539dd
commit 7f0d06637d
6 files changed
+56 -56

No files matched your search

+2 -2
View File
@@ -4,8 +4,8 @@ import numpy as np
from scipy import ndimage
from aaredaqlib.coordinate import Coordinate
from aaredaqlib.models import CrystalSize, CenterOfMassModel
from aaredaqlib.raster_grid import RasterGridRequest
from aaredaqlib.models import CrystalSize
from aaredaqlib.raster_grid import RasterGridRequest, CenterOfMassModel
from aaredaqlib.logger_config import setup_logger
logger = setup_logger('aareDAQ')
+1 -49
View File
@@ -9,7 +9,6 @@ from pydantic import BaseModel, Field, field_validator, AfterValidator
from aaredaqlib.coordinate import Coordinate, positive_coords
from aaredaqlib.diffraction_geometry import DiffractionGeometry
from aaredaqlib.raster_grid import RasterGridRequest
from aaredaqlib.sample_geometry import SampleGeometryModel
from jfjoch_client.models.scan_result import ScanResult
@@ -409,16 +408,6 @@ class SampleShortInfo(BaseModel):
class SampleShortInfoList(BaseModel):
s: List[SampleShortInfo]
class SimpleScanParameters(BaseModel):
filename: Optional[str] = None
dtz: float = 150
exp_time_s: float = 0.02
start_omega_deg:float = 0
incr_omega_deg: float = 0.2
steps: int = 1800
transmission: Annotated[float, Field(ge=0.0, le=1.0)] = 1.0
class BeamMarkCoeffModel(BaseModel):
"""
Model to calculate beam center for a given zoom level based on a quadratic approximation
@@ -780,41 +769,4 @@ class SimpleScanParameters(BaseModel):
beam_size_y_um: float | None = None
dose_rate_MGy_s: float | None = None
d_vis: float | None = None
d_tar: float | None = None
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":
# Return None if either coordinate is NaN
if np.isnan(n_x) or np.isnan(n_y):
return None
return cls(n_x=float(n_x), n_y=float(n_y))
def get_com_mm(self, r:RasterGridRequest) -> Coordinate:
#defines COM in mm at beam position, relative to the top left corner of grid
return Coordinate(x=(self.n_x+0.5)*r.grid_size_mm.x, y=(self.n_y+0.5)*r.grid_size_mm.y)
def get_com_pxl(self, r:RasterGridRequest, geom:SampleGeometryModel) -> Coordinate:
#defines COM in pixels at beam position, relative to the top left corner of grid
com_mm = self.get_com_mm(r)
return Coordinate(x=com_mm.x/geom.pixel_in_mm, y=com_mm.y/geom.pixel_in_mm)
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))
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)]
d_tar: float | None = None
+42
View File
@@ -1,5 +1,7 @@
from typing import Annotated, List
import numpy as np
from jfjoch_client.models.scan_result import ScanResult
from pydantic import Field, AfterValidator, BaseModel
@@ -24,6 +26,7 @@ class RasterGridRequest(BaseModel):
# If None, measure from the current position.
smargon_top_left: SmargonCoordinate | None
# omega angle
omega_deg: float = 0.0
@@ -40,9 +43,48 @@ class RasterGridRequest(BaseModel):
return geom.smargon_to_beamline(geom.smargon.sh_mm)
return geom.smargon_to_beamline(self.smargon_top_left.sh_mm)
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":
# Return None if either coordinate is NaN
if np.isnan(n_x) or np.isnan(n_y):
return None
return cls(n_x=float(n_x), n_y=float(n_y))
def get_com_mm(self, r:RasterGridRequest) -> Coordinate:
#defines COM in mm at beam position, relative to the top left corner of grid
return Coordinate(x=(self.n_x+0.5)*r.grid_size_mm.x, y=(self.n_y+0.5)*r.grid_size_mm.y)
def get_com_pxl(self, r:RasterGridRequest, geom:SampleGeometryModel) -> Coordinate:
#defines COM in pixels at beam position, relative to the top left corner of grid
com_mm = self.get_com_mm(r)
return Coordinate(x=com_mm.x/geom.pixel_in_mm, y=com_mm.y/geom.pixel_in_mm)
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))
class CompletedRasterGridElem(BaseModel):
request: RasterGridRequest
result: ScanResult
centre_of_mass: CenterOfMassModel | None
class CompletedRasterGrid(BaseModel):
r: List[CompletedRasterGridElem]
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)]
+2 -2
View File
@@ -29,11 +29,11 @@ from aaredaqlib.models import (
PuckLoadedInfo,
DewarAddress,
SampleShortInfoList,
DAQStatusModel, SessionStatus, RasterPayloadModel, CenterOfMassModel,
DAQStatusModel, SessionStatus,
)
from aaredaqlib.beamline import MXBeamline
from aaredaqlib.raster_grid import RasterGridRequest, CompletedRasterGrid
from aaredaqlib.raster_grid import RasterGridRequest, CompletedRasterGrid, RasterPayloadModel, CenterOfMassModel
from aaredaqlib.rotation_scan import RotationScanRequest
from aaredaqlib.sample_geometry import SampleGeometryModel
+1 -1
View File
@@ -603,7 +603,7 @@ class AareDAQ:
except Exception as e:
logger.error(f"Exception ingesting grid scan: {e}")
self.__devs.reflector_up = False
return CompletedRasterGridElem(request=copy.deepcopy(r), result=result)
return CompletedRasterGridElem(request=copy.deepcopy(r), result=result, centre_of_mass=com)
def measure_raster(self, r: RasterGridRequest, auto: bool) -> CompletedRasterGrid:
self.__cfg.try_set_busy(timeout=ceil(360))
@@ -235,7 +235,8 @@ class RasterGridManager(QObject):
if 0 <= cell_x < n_x and 0 <= cell_y < n_y:
cell = cell_y * n_x + cell_x
if self.__loaded_image_prefix != grid.result.file_prefix or self.__loaded_image_index != grid.result.images[cell].number:
if (self.__loaded_image_prefix != grid.result.file_prefix or
self.__loaded_image_index != grid.result.images[cell].number):
self.__loaded_image_prefix = grid.result.file_prefix
self.__loaded_image_index = grid.result.images[cell].number
print(f"Load {grid.result.file_prefix} {grid.result.images[cell].number}")
@@ -454,7 +455,12 @@ class RasterGridManager(QObject):
self.__active_grid.n_x = 0
self.__active_grid.n_y = 0
if last_raster is not None and last_raster.result.file_prefix is not None:
self.image_selected.emit("http://sls-gpu-001:8080",0) #last_raster.result.file_prefix, 0)
com = last_raster.centre_of_mass
if com:
cell = com.max_image
else:
cell = 0
self.image_selected.emit("http://sls-gpu-001:8080",cell) #last_raster.result.file_prefix, 0)
self.completed_grid_updated.emit()
@Slot(int, bool)