workflows.py: up the exposure time on xtal snapshot to 1 ms.

This commit is contained in:
appleb_m
2026-06-25 16:28:49 +02:00
parent 4d075eb79a
commit f7b5008be5
5 changed files with 44 additions and 16 deletions
+16 -6
View File
@@ -280,20 +280,30 @@ def get_com_image_number(com, images):
return image.number
return None
def raster_centre_of_mass(result_array, images) -> CenterOfMassModel | None:
# grid_mm_x and grid_mm_y are relative to the top left corner of raster grid
com = ndimage.center_of_mass(result_array)
# com = ndimage.center_of_mass(result_array)
# if com and not np.isnan(com[0]) and not np.isnan(com[1]):
# logger.info(f"Center of mass: {com}")
# max_image = get_com_image_number(com, images)
# return CenterOfMassModel(n_x=com[0], n_y=com[1], max_image=max_image)
# elif com and np.isnan(com[0]) and np.isnan(com[1]):
# logger.warning(f"Center of mass is nan: {com[0]}, {com[1]}")
# return None
# else:
# logger.warning("No valid center of mass found")
# return None
score_array = compute_crystal_score_array(images)
com = _max_cell(score_array)
if com and not np.isnan(com[0]) and not np.isnan(com[1]):
logger.info(f"Center of mass: {com}")
logger.info(f"Highest score: {com}")
max_image = get_com_image_number(com, images)
return CenterOfMassModel(n_x=com[0], n_y=com[1], max_image=max_image)
elif com and np.isnan(com[0]) and np.isnan(com[1]):
logger.warning(f"Center of mass is nan: {com[0]}, {com[1]}")
logger.warning(f"Highest score is nan: {com[0]}, {com[1]}")
return None
else:
logger.warning("No valid center of mass found")
logger.warning("No valid score found")
return None
def has_sufficient_low_res_spots(
+11 -1
View File
@@ -1353,6 +1353,10 @@ class AareDAQ:
),
)
else:
# Resolve + validate the requested dtz (sets cfg.dtz, requires
# request.dtz) BEFORE configuring JFJoch, so JFJoch receives the
# commanded target rather than the live, still-in-transit position.
self.__setup_datacollection(request=grid_request)
logger.debug(f"Is detector simulated? {self.__cfg.simulated_detector}")
if not self.__cfg.simulated_detector:
logger.info(f"initialise detector for raster")
@@ -1362,7 +1366,6 @@ class AareDAQ:
else:
logger.info("Simulated detector mode enabled; using fake raster result.")
self.__setup_datacollection(request=grid_request)
self.__set_state(BeamlineStateEnum.DataCollection)
raster_result = raster_service.execute(grid_request)
result = CompletedRasterGrid(r=[raster_result])
@@ -2052,8 +2055,15 @@ class AareDAQ:
self.__devs.aerotech_omega = request_omega
if request.dtz is not None:
if request.dtz < self.__cfg.cached_dtz_low:
raise ValueError(f"Requested DTZ {request.dtz} is less than low detector limit {self.__cfg.cached_dtz_low}")
elif request.dtz > self.__cfg.cached_dtz_high:
raise ValueError(f"Requested DTZ {request.dtz} exceeds high detector limit {self.__cfg.cached_dtz_high}")
logger.info(f'requesting dtz to move to {request.dtz}')
self.__cfg.dtz = request.dtz
else:
raise ValueError("No DTZ specified")
if self.sample is not None and self.sample.db_id is not None:
sample_id = self.sample.db_id
+2 -2
View File
@@ -85,13 +85,13 @@ def sa2rse(devs: BeamlineDevices, cfg: BeamlineConfig):
def sa2xtal_snapshot(devs:BeamlineDevices, cfg:BeamlineConfig):
logger.info("SA to Xtal Snapshot")
devs.samcam_settings = SampleCameraSettings(gain=0.0, exposure=0.0005)
devs.samcam_settings = SampleCameraSettings(gain=0.0, exposure=0.001)
logger.debug(f"new sam cam settings: {devs.samcam_settings}")
devs.bec_worker.move_to(BeamlineState.XTAL_SNAPSHOT)
def dc2xtal_snapshot(devs:BeamlineDevices, cfg:BeamlineConfig):
logger.debug("DC to Xtal Snapshot")
devs.samcam_settings = SampleCameraSettings(gain=0.0, exposure=0.0005)
devs.samcam_settings = SampleCameraSettings(gain=0.0, exposure=0.001)
logger.debug(f"new sam cam settings: {devs.samcam_settings}")
devs.bec_worker.move_to(BeamlineState.XTAL_SNAPSHOT)
@@ -93,10 +93,11 @@ class RasterDataCollectionPanel(ScanSettingsPanel):
self.metric_combo.addItem("Spot ratio (ice/low res.)", RasterGridMetric.SPOTS_ICE_LOW_RES)
self.metric_combo.addItem("Background estimate", RasterGridMetric.BKG)
self.metric_combo.addItem("Indexing result", RasterGridMetric.INDEXING)
self.metric_combo.addItem("Profile Radius", RasterGridMetric.PR)
self.metric_combo.addItem("Profile Radius (Score)", RasterGridMetric.PR) # JD: repurposing PR for testing scoring
self.metric_combo.addItem("B-factor", RasterGridMetric.BFACTOR)
self.metric_combo.addItem("Resolution (ML est.)", RasterGridMetric.RES)
self.metric_combo.setCurrentIndex(self.metric_combo.findData(RasterGridMetric.PR)) # JD: repurposing PR for testing scoring
self.metric_combo.currentIndexChanged.connect(self.metric_changed)
self._layout.addWidget(self.metric_combo, 7, 1, 1, 3)
+13 -6
View File
@@ -10,6 +10,7 @@ from typing import List, Tuple
from aare.common.beamline import mx_beamline, get_jfjoch_url
from aare.common.coordinate import Coordinate, SmargonCoordinate
from aare.common.models import DAQStatusModel
from aare.common.find_xtal import compute_crystal_score_array
from aare.common.raster_grid import RasterGridRequest, CompletedRasterGrid, CompletedRasterGridElem
from aare.common.sample_geometry import SampleGeometryModel
@@ -22,7 +23,7 @@ class RasterGridMetric(Enum):
BKG = 0
SPOTS = 1
INDEXING = 2
PR = 3
PR = 3 # JD: repurposing PR for testing scoring
BFACTOR = 4
SPOTS_LOW_RES = 5
RES = 6
@@ -121,7 +122,8 @@ class RasterGridManager(QObject):
self.__beam_size_mm = geom.beam_size_mm
self.__geom = geom
self.__metric = RasterGridMetric.SPOTS_LOW_RES
# self.__metric = RasterGridMetric.SPOTS_LOW_RES
self.__metric = RasterGridMetric.PR # JD: repurposing PR for testing scoring
self.__loaded_image_prefix = None
self.__loaded_image_index = None
@@ -373,8 +375,11 @@ class RasterGridManager(QObject):
if grid.result.images[cell].b is not None and grid.result.images[cell].b >= 0:
txt += f"B-factor {grid.result.images[cell].b:.2f}<br/>"
if grid.result.images[cell].pr is not None and grid.result.images[cell].pr >= 0:
txt += f"Profile Radius {grid.result.images[cell].pr:.2f}"
# if grid.result.images[cell].pr is not None and grid.result.images[cell].pr >= 0: # JD: repurposing PR for testing scoring
# txt += f"Profile Radius {grid.result.images[cell].pr:.2f}"
if grid.result.images[cell].nx is not None and grid.result.images[cell].ny is not None:
score = compute_crystal_score_array(grid.result.images)
txt += f"Profile Radius (Score) {score[grid.result.images[cell].nx, grid.result.images[cell].ny]:.2f}"
return txt
return None
@@ -461,8 +466,10 @@ class RasterGridManager(QObject):
v = [obj.bkg for obj in i.result.images]
case RasterGridMetric.INDEXING:
v = [obj.index for obj in i.result.images]
case RasterGridMetric.PR:
v = [obj.index / max(obj.spots_low_res, 1) for obj in i.result.images]
case RasterGridMetric.PR: # JD: repurposing PR for testing scoring
# v = [obj.index / max(obj.spots_low_res, 1) for obj in i.result.images]
score = compute_crystal_score_array(i.result.images)
v = [score[obj.nx, obj.ny] if obj.nx is not None and obj.ny is not None else None for obj in i.result.images]
case RasterGridMetric.BFACTOR:
v = [obj.b for obj in i.result.images]
case RasterGridMetric.RES: