DAQ/GUI: fixed a raster bug where it was either moving to smargon 0, or not moving to the start of the mlbox.
This commit is contained in:
+391
-43
@@ -33,6 +33,12 @@ from aare.common.models import (
|
||||
DAQStatusModel, BeamlineStatus, SessionStatus, SampleCameraSettings, ZoomModeEnum,
|
||||
SimpleScanParameters, MLBoxModel, FluorescenceSpectrumParameterModel,
|
||||
FluorescenceSpectrumOutputModel, DAQOperation, LoopCenteringResult)
|
||||
from aare.common.automation_models import (
|
||||
AutomationProgress,
|
||||
StepState,
|
||||
StepStatus,
|
||||
WorkflowStateKind,
|
||||
)
|
||||
from aare.common.raster_grid import RasterGridRequest, CompletedRasterGrid, CompletedRasterGridElem
|
||||
from aare.common.rotation_scan import RotationScanRequest, CompletedRotationScan
|
||||
from aare.common.sample_geometry import SampleGeometryModel
|
||||
@@ -233,12 +239,28 @@ class AareDAQ:
|
||||
error: The exception that occurred
|
||||
event_type: Type of event to send to database - "mount", "alc", "axc", or "generic"
|
||||
"""
|
||||
sample_name = getattr(sample, "sample_name", None)
|
||||
sample_id = getattr(sample, "db_id", None)
|
||||
|
||||
logger.exception(
|
||||
"Operation failed",
|
||||
extra={
|
||||
"operation": operation.value,
|
||||
"event_type": str(event_type),
|
||||
"sample_name": sample_name,
|
||||
"sample_id": sample_id,
|
||||
"additional_comment": additional_comment,
|
||||
},
|
||||
)
|
||||
|
||||
if sample is None:
|
||||
logger.error(f"Error in {operation.value}: {error}")
|
||||
return
|
||||
|
||||
comment = f"Error in {operation.value}: {error}"
|
||||
if additional_comment is not None:
|
||||
comment += f" Additional comment: {additional_comment}"
|
||||
|
||||
try:
|
||||
self.__aare.send_sample_event(
|
||||
sample,
|
||||
@@ -246,7 +268,14 @@ class AareDAQ:
|
||||
comment=comment,
|
||||
)
|
||||
except Exception as db_error:
|
||||
logger.error(f"Failed to report {operation.value} error to database: {db_error}")
|
||||
logger.exception(
|
||||
"Failed to report operation error to database",
|
||||
extra={
|
||||
"operation": operation.value,
|
||||
"sample_name": sample_name,
|
||||
"sample_id": sample_id,
|
||||
},
|
||||
)
|
||||
|
||||
#todo make sure these functions are correctly implemented!
|
||||
#Operation handlers should handle database communication and beamline state changes,
|
||||
@@ -345,16 +374,68 @@ class AareDAQ:
|
||||
CompletedRasterGrid result or None if failed
|
||||
"""
|
||||
try:
|
||||
self.__setup_datacollection(request=grid_request)
|
||||
logger.info(
|
||||
"Starting raster sequence",
|
||||
extra={
|
||||
"auto_center": auto_center,
|
||||
"file_prefix": grid_request.file_prefix,
|
||||
"omega_deg": grid_request.omega_deg,
|
||||
"dtz": grid_request.dtz,
|
||||
"transmission": grid_request.transmission,
|
||||
"n_x": grid_request.n_x,
|
||||
"n_y": grid_request.n_y,
|
||||
"grid_size_x_mm": getattr(grid_request.grid_size_mm, "x", None),
|
||||
"grid_size_y_mm": getattr(grid_request.grid_size_mm, "y", None),
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
"sample_name": getattr(self.sample, "sample_name", None),
|
||||
},
|
||||
)
|
||||
|
||||
if auto_center:
|
||||
setup_request = copy.deepcopy(grid_request)
|
||||
setup_request.smargon_top_left = None
|
||||
self.__setup_datacollection(request=setup_request)
|
||||
result = self.__auto_center(grid_request)
|
||||
if result is None:
|
||||
logger.error(
|
||||
"Raster sequence returned no result after auto-centering",
|
||||
extra={
|
||||
"file_prefix": grid_request.file_prefix,
|
||||
"omega_deg": grid_request.omega_deg,
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
"sample_name": getattr(self.sample, "sample_name", None),
|
||||
},
|
||||
)
|
||||
else:
|
||||
self.__setup_datacollection(request=grid_request)
|
||||
self.__set_state(BeamlineStateEnum.DataCollection)
|
||||
raster_result = self.__raster(grid_request)
|
||||
result = CompletedRasterGrid(r=[raster_result])
|
||||
self.__set_state(BeamlineStateEnum.SampleAlignment)
|
||||
|
||||
if result is not None:
|
||||
logger.info(
|
||||
"Raster sequence completed",
|
||||
extra={
|
||||
"auto_center": auto_center,
|
||||
"file_prefix": grid_request.file_prefix,
|
||||
"result_count": len(result.r) if hasattr(result, "r") and result.r is not None else None,
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
},
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
except JFJochCommunicationError as e:
|
||||
logger.error(f"Raster sequence failed due to JFJoch Communication error: {e}")
|
||||
logger.exception(
|
||||
"Raster sequence failed due to JFJoch communication error",
|
||||
extra={
|
||||
"file_prefix": grid_request.file_prefix,
|
||||
"omega_deg": grid_request.omega_deg,
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
"sample_name": getattr(self.sample, "sample_name", None),
|
||||
},
|
||||
)
|
||||
self._handle_operation_error(
|
||||
operation=DAQOperation.RASTER,
|
||||
sample=self.sample,
|
||||
@@ -364,7 +445,20 @@ class AareDAQ:
|
||||
)
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Raster sequence failed: {e}")
|
||||
logger.exception(
|
||||
"Raster sequence failed",
|
||||
extra={
|
||||
"auto_center": auto_center,
|
||||
"file_prefix": grid_request.file_prefix,
|
||||
"omega_deg": grid_request.omega_deg,
|
||||
"dtz": grid_request.dtz,
|
||||
"transmission": grid_request.transmission,
|
||||
"n_x": grid_request.n_x,
|
||||
"n_y": grid_request.n_y,
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
"sample_name": getattr(self.sample, "sample_name", None),
|
||||
},
|
||||
)
|
||||
self._handle_operation_error(
|
||||
operation=DAQOperation.RASTER,
|
||||
sample=self.sample,
|
||||
@@ -387,6 +481,7 @@ class AareDAQ:
|
||||
self.__setup_datacollection(request=rotation_request)
|
||||
if self.sample is not None and self.sample.db_id is not None:
|
||||
self.__aare.send_sample_event(self.sample, SampleEventType.COLLECTING)
|
||||
self.__set_state(BeamlineStateEnum.DataCollection)
|
||||
result = self.__rotation(rotation_request)
|
||||
self.__set_state(BeamlineStateEnum.SampleAlignment)
|
||||
if self.sample is not None and self.sample.db_id is not None:
|
||||
@@ -615,7 +710,7 @@ class AareDAQ:
|
||||
|
||||
def __omega(self, val: float):
|
||||
self.__saved_box = None
|
||||
print(f"Set omega to {val}")
|
||||
logger.info(f"Set omega to {val}")
|
||||
if -2000 < val < 2000:
|
||||
try:
|
||||
self.__devs.aerotech_omega = val
|
||||
@@ -664,7 +759,7 @@ class AareDAQ:
|
||||
@front_light.setter
|
||||
def front_light(self, f: float):
|
||||
conv = (f / 100.0 * 1.5) + 1.0
|
||||
print(f"Light {f} -> {conv}")
|
||||
logger.info(f"Light {f} -> {conv}")
|
||||
self.__devs.lamp_light = conv
|
||||
|
||||
@property
|
||||
@@ -680,7 +775,7 @@ class AareDAQ:
|
||||
@back_light.setter
|
||||
def back_light(self, f: float):
|
||||
conv = f / 100.0 * 3.0
|
||||
print(f"Backlight {f} -> {conv}")
|
||||
logger.info(f"Backlight {f} -> {conv}")
|
||||
self.__devs.back_light = conv
|
||||
|
||||
@property
|
||||
@@ -905,7 +1000,7 @@ class AareDAQ:
|
||||
self.__devs.samcam_auto(AutoEnum.ONCE)
|
||||
|
||||
def __auto_center(self, request: RasterGridRequest) -> CompletedRasterGrid | None:
|
||||
#TODO do we need to handle the two grid scans differently?
|
||||
# TODO do we need to handle the two grid scans differently?
|
||||
sample = self.sample
|
||||
|
||||
if sample is None:
|
||||
@@ -913,14 +1008,54 @@ class AareDAQ:
|
||||
|
||||
old_prefix = request.file_prefix
|
||||
geom = self.sample_geometry
|
||||
|
||||
logger.info(
|
||||
"Starting auto-center raster workflow",
|
||||
extra={
|
||||
"sample_id": getattr(sample, "db_id", None),
|
||||
"sample_name": getattr(sample, "sample_name", None),
|
||||
"omega_deg": geom.omega_deg,
|
||||
"current_sh_x_mm": geom.smargon.sh_mm.x,
|
||||
"current_sh_y_mm": geom.smargon.sh_mm.y,
|
||||
"current_sh_z_mm": geom.smargon.sh_mm.z,
|
||||
"beam_x_pxl": geom.beam_location_pxl.x,
|
||||
"beam_y_pxl": geom.beam_location_pxl.y,
|
||||
"pixel_in_mm": geom.pixel_in_mm,
|
||||
"file_prefix": old_prefix,
|
||||
},
|
||||
)
|
||||
|
||||
r = self.__ml_bounding_box(sample.db_id, f"ml_{geom.omega_deg:.2f}deg")
|
||||
|
||||
if r is None:
|
||||
logger.warning(
|
||||
"No ML bounding box found at primary angle during auto-center raster",
|
||||
extra={
|
||||
"sample_id": getattr(sample, "db_id", None),
|
||||
"omega_deg": geom.omega_deg,
|
||||
"file_prefix": old_prefix,
|
||||
},
|
||||
)
|
||||
self.__devs.aerotech_omega = geom.omega_deg + 90.0
|
||||
time.sleep(0.2)
|
||||
r = self.__ml_bounding_box(sample.db_id, f"ml_{geom.omega_deg + 90.0:.2f}deg")
|
||||
|
||||
if r is not None:
|
||||
logger.info(
|
||||
"ML bounding box found for auto-center raster",
|
||||
extra={
|
||||
"sample_id": getattr(sample, "db_id", None),
|
||||
"ml_omega_deg": r.omega_deg,
|
||||
"ml_n_x": r.n_x,
|
||||
"ml_n_y": r.n_y,
|
||||
"ml_grid_size_x_mm": getattr(r.grid_size_mm, "x", None),
|
||||
"ml_grid_size_y_mm": getattr(r.grid_size_mm, "y", None),
|
||||
"ml_top_left_x_mm": getattr(getattr(r.smargon_top_left, "sh_mm", None), "x", None),
|
||||
"ml_top_left_y_mm": getattr(getattr(r.smargon_top_left, "sh_mm", None), "y", None),
|
||||
"ml_top_left_z_mm": getattr(getattr(r.smargon_top_left, "sh_mm", None), "z", None),
|
||||
},
|
||||
)
|
||||
self.__set_state(BeamlineStateEnum.DataCollection)
|
||||
geom = self.sample_geometry
|
||||
grid = copy.deepcopy(request)
|
||||
grid.smargon_top_left = r.smargon_top_left
|
||||
@@ -929,32 +1064,81 @@ class AareDAQ:
|
||||
grid.n_y = r.n_y
|
||||
grid.file_prefix = f"{old_prefix}_{grid.omega_deg}deg"
|
||||
grid.omega_deg = geom.omega_deg
|
||||
|
||||
logger.info(
|
||||
"Running first auto-center raster",
|
||||
extra={
|
||||
"file_prefix": grid.file_prefix,
|
||||
"omega_deg": grid.omega_deg,
|
||||
"n_x": grid.n_x,
|
||||
"n_y": grid.n_y,
|
||||
"top_left_x_mm": getattr(grid.smargon_top_left.sh_mm, "x", None),
|
||||
"top_left_y_mm": getattr(grid.smargon_top_left.sh_mm, "y", None),
|
||||
"top_left_z_mm": getattr(grid.smargon_top_left.sh_mm, "z", None),
|
||||
},
|
||||
)
|
||||
res1 = self.__raster(grid)
|
||||
|
||||
grid.omega_deg += 90
|
||||
self.__devs.aerotech_omega = grid.omega_deg
|
||||
self.__set_state(BeamlineStateEnum.XtalSnapshot)
|
||||
|
||||
grid.n_x = 1
|
||||
#TODO generate y scan rather than had code for 1x50
|
||||
# TODO generate y scan rather than had code for 1x50
|
||||
grid.n_y = 50
|
||||
grid.file_prefix = f"{old_prefix}_{grid.omega_deg}deg"
|
||||
grid.grid_size_mm = Coordinate(x=geom.beam_size_mm.x, y=geom.beam_size_mm.y * 0.25)
|
||||
offset = Coordinate(x=-grid.grid_size_mm.x/2.0, y=-(grid.n_y + 0.5) * grid.grid_size_mm.y / 2.0)
|
||||
offset = Coordinate(x=-grid.grid_size_mm.x / 2.0, y=-(grid.n_y + 0.5) * grid.grid_size_mm.y / 2.0)
|
||||
geom = self.sample_geometry
|
||||
logger.debug(f"set offset y scan {offset}")
|
||||
grid.smargon_top_left = geom.translate_smargon(offset)
|
||||
|
||||
logger.info(
|
||||
"Prepared second auto-center raster",
|
||||
extra={
|
||||
"file_prefix": grid.file_prefix,
|
||||
"omega_deg": grid.omega_deg,
|
||||
"offset_x_mm": offset.x,
|
||||
"offset_y_mm": offset.y,
|
||||
"offset_z_mm": offset.z,
|
||||
"top_left_x_mm": getattr(grid.smargon_top_left.sh_mm, "x", None),
|
||||
"top_left_y_mm": getattr(grid.smargon_top_left.sh_mm, "y", None),
|
||||
"top_left_z_mm": getattr(grid.smargon_top_left.sh_mm, "z", None),
|
||||
},
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Running second auto-center raster",
|
||||
extra={
|
||||
"file_prefix": grid.file_prefix,
|
||||
"omega_deg": grid.omega_deg,
|
||||
"n_x": grid.n_x,
|
||||
"n_y": grid.n_y,
|
||||
},
|
||||
)
|
||||
res2 = self.__raster(grid)
|
||||
return CompletedRasterGrid(r=[res1, res2])
|
||||
else:
|
||||
logger.error(
|
||||
"Auto-center raster aborted because no ML bounding box was found at either angle",
|
||||
extra={
|
||||
"sample_id": getattr(sample, "db_id", None),
|
||||
"sample_name": getattr(sample, "sample_name", None),
|
||||
"primary_omega_deg": geom.omega_deg,
|
||||
"secondary_omega_deg": geom.omega_deg + 90.0,
|
||||
"file_prefix": old_prefix,
|
||||
},
|
||||
)
|
||||
return None
|
||||
|
||||
def __setup_datacollection(self, request: RasterGridRequest | RotationScanRequest, screening: bool = False):
|
||||
request_omega = getattr(request, "omega_deg", None)
|
||||
if request_omega is None:
|
||||
request_omega = getattr(request, "start_omega_deg", None)
|
||||
|
||||
if request.omega_deg is not None:
|
||||
self.__devs.aerotech_omega = request.omega_deg
|
||||
|
||||
else:
|
||||
omega = self.omega
|
||||
if request_omega is not None:
|
||||
logger.info(f"requesting omega to move to {request_omega}")
|
||||
self.__devs.aerotech_omega = request_omega
|
||||
|
||||
if request.dtz is not None:
|
||||
logger.info(f'requesting dtz to move to {request.dtz}')
|
||||
@@ -968,27 +1152,50 @@ class AareDAQ:
|
||||
screenshot_name = f"{sample_id}_before_raster"
|
||||
else:
|
||||
screenshot_name = f"{sample_id}_before_data_collection"
|
||||
# self.auto_exposure()
|
||||
# time.sleep(0.2)
|
||||
self.save_screenshot_db(sample_id, screenshot_name)
|
||||
|
||||
self.__set_state(BeamlineStateEnum.DataCollection)
|
||||
|
||||
if request.transmission is not None:
|
||||
logger.info(f'requesting transmission to move to {request.transmission}')
|
||||
self.__devs.transmission = request.transmission
|
||||
|
||||
if hasattr(request, 'start') and request.start is not None:
|
||||
self.__devs.smargon_pos = request.start
|
||||
logger.info(f'requesting smargon to move to {request.start}')
|
||||
elif hasattr(request, 'smargon_top_left') and request.smargon_top_left is not None:
|
||||
logger.info(f'requesting smargon to move to {request.smargon_top_left}')
|
||||
self.__devs.set_smargon_pos(SmargonCoordinate(sh_mm=request.smargon_top_left.sh_mm,
|
||||
phi_deg=request.smargon_top_left.phi_deg,
|
||||
chi_deg=request.smargon_top_left.chi_deg))
|
||||
start_pos = getattr(request, "start", None)
|
||||
if start_pos is not None:
|
||||
logger.info(f'requesting smargon to move to {start_pos}')
|
||||
self.__devs.smargon_pos = start_pos
|
||||
else:
|
||||
smargon_top_left = getattr(request, "smargon_top_left", None)
|
||||
has_valid_smargon_target = (
|
||||
smargon_top_left is not None
|
||||
and getattr(smargon_top_left, "sh_mm", None) is not None
|
||||
)
|
||||
|
||||
is_zero_placeholder = (
|
||||
has_valid_smargon_target
|
||||
and abs(smargon_top_left.sh_mm.x) < 1e-6
|
||||
and abs(smargon_top_left.sh_mm.y) < 1e-6
|
||||
and abs(smargon_top_left.sh_mm.z) < 1e-6
|
||||
and abs(smargon_top_left.phi_deg) < 1e-6
|
||||
and abs(smargon_top_left.chi_deg) < 1e-6
|
||||
)
|
||||
|
||||
if has_valid_smargon_target and not is_zero_placeholder:
|
||||
logger.info(f'requesting smargon to move to {smargon_top_left}')
|
||||
self.__devs.set_smargon_pos(
|
||||
SmargonCoordinate(
|
||||
sh_mm=smargon_top_left.sh_mm,
|
||||
phi_deg=smargon_top_left.phi_deg,
|
||||
chi_deg=smargon_top_left.chi_deg,
|
||||
)
|
||||
)
|
||||
else:
|
||||
logger.debug("No explicit smargon target in request; skipping pre-datacollection smargon move")
|
||||
|
||||
self.__devs.smargon_wait(timeout=180)
|
||||
#todo ADD TRANSMISSION
|
||||
#if request.transmission is not None:
|
||||
# self.__devs.transmission.wait()
|
||||
self.__devs.smargon_wait(timeout=180)
|
||||
|
||||
return
|
||||
|
||||
def _build_fake_scan_result(self, *, file_prefix: str | None, image_count: int) -> ScanResult:
|
||||
@@ -1029,11 +1236,33 @@ class AareDAQ:
|
||||
)
|
||||
|
||||
def __raster(self, request: RasterGridRequest) -> CompletedRasterGridElem:
|
||||
smargon_top_left =request.smargon_top_left
|
||||
self.__devs.set_smargon_pos(
|
||||
SmargonCoordinate(
|
||||
sh_mm=smargon_top_left.sh_mm,
|
||||
phi_deg=smargon_top_left.phi_deg,
|
||||
chi_deg=smargon_top_left.chi_deg,
|
||||
)
|
||||
)
|
||||
status = self.status
|
||||
logger.info(f"raster status {status}")
|
||||
logger.info(f'raster grid request: {request}')
|
||||
logger.info(
|
||||
"Starting raster acquisition",
|
||||
extra={
|
||||
"file_prefix": request.file_prefix,
|
||||
"omega_deg": request.omega_deg,
|
||||
"dtz": request.dtz,
|
||||
"transmission": request.transmission,
|
||||
"n_x": request.n_x,
|
||||
"n_y": request.n_y,
|
||||
"grid_size_x_mm": getattr(request.grid_size_mm, "x", None),
|
||||
"grid_size_y_mm": getattr(request.grid_size_mm, "y", None),
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
"sample_name": getattr(self.sample, "sample_name", None),
|
||||
"state": getattr(status, "state", None),
|
||||
},
|
||||
)
|
||||
|
||||
total_time = request.exp_time_s*request.n_x*request.n_y+request.n_y*0.3
|
||||
total_time = request.exp_time_s * request.n_x * request.n_y + request.n_y * 0.3
|
||||
|
||||
try:
|
||||
if self.sample is not None and self.sample.db_id is not None:
|
||||
@@ -1058,7 +1287,7 @@ class AareDAQ:
|
||||
)
|
||||
|
||||
self.__devs.aerotech.wait_till_done(timeout=int(round(total_time * 2, 0)))
|
||||
#go back to aerotech x,y,z home not U home (0 degrees).
|
||||
# go back to aerotech x,y,z home not U home (0 degrees).
|
||||
if isinstance(self.__cfg.abr_meas_pos, Coordinate):
|
||||
coord = self.__cfg.abr_meas_pos
|
||||
else:
|
||||
@@ -1073,6 +1302,22 @@ class AareDAQ:
|
||||
y = ((request.n_y - 1) * request.grid_size_mm.y) / 2.0
|
||||
grid_centre_offset = self.sample_geometry.smargon_nudge(Coordinate(x=x, y=y))
|
||||
|
||||
logger.info(
|
||||
"Calculated raster centre offset",
|
||||
extra={
|
||||
"file_prefix": request.file_prefix,
|
||||
"omega_deg": request.omega_deg,
|
||||
"centre_offset_x_mm": grid_centre_offset.x,
|
||||
"centre_offset_y_mm": grid_centre_offset.y,
|
||||
"centre_offset_z_mm": grid_centre_offset.z,
|
||||
"grid_half_width_x_mm": x,
|
||||
"grid_half_height_y_mm": y,
|
||||
"top_left_x_mm": getattr(request.smargon_top_left.sh_mm, "x", None),
|
||||
"top_left_y_mm": getattr(request.smargon_top_left.sh_mm, "y", None),
|
||||
"top_left_z_mm": getattr(request.smargon_top_left.sh_mm, "z", None),
|
||||
},
|
||||
)
|
||||
|
||||
logger.info(f"moving Smargon to grid centre offset {grid_centre_offset}")
|
||||
|
||||
grid_centre_smargon = SmargonCoordinate(
|
||||
@@ -1083,6 +1328,19 @@ class AareDAQ:
|
||||
self.__devs.smargon_pos = grid_centre_smargon
|
||||
self.__devs.smargon_wait(timeout=180)
|
||||
|
||||
logger.info(
|
||||
"Moved Smargon to raster centre",
|
||||
extra={
|
||||
"file_prefix": request.file_prefix,
|
||||
"omega_deg": request.omega_deg,
|
||||
"centre_sh_x_mm": grid_centre_smargon.sh_mm.x,
|
||||
"centre_sh_y_mm": grid_centre_smargon.sh_mm.y,
|
||||
"centre_sh_z_mm": grid_centre_smargon.sh_mm.z,
|
||||
"centre_phi_deg": grid_centre_smargon.phi_deg,
|
||||
"centre_chi_deg": grid_centre_smargon.chi_deg,
|
||||
},
|
||||
)
|
||||
|
||||
if self.__cfg.simulated_detector:
|
||||
scan_result = self._build_fake_scan_result(
|
||||
file_prefix=request.file_prefix,
|
||||
@@ -1091,16 +1349,24 @@ class AareDAQ:
|
||||
else:
|
||||
scan_result = self.__jfjoch.wait_till_done(60)
|
||||
if scan_result is None:
|
||||
logger.warning("JFJoch returned no ScanResult")#; using fake result for raster scan.")
|
||||
# scan_result = self._build_fake_scan_result(
|
||||
# file_prefix=request.file_prefix,
|
||||
# image_count=request.n_x * request.n_y,
|
||||
# )
|
||||
logger.error(
|
||||
"JFJoch returned no ScanResult for raster",
|
||||
extra={
|
||||
"file_prefix": request.file_prefix,
|
||||
"omega_deg": request.omega_deg,
|
||||
"n_x": request.n_x,
|
||||
"n_y": request.n_y,
|
||||
"exp_time_s": request.exp_time_s,
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
"sample_name": getattr(self.sample, "sample_name", None),
|
||||
},
|
||||
)
|
||||
|
||||
sample_id = self.sample.db_id if self.sample and self.sample.db_id is not None else None
|
||||
if sample_id:
|
||||
logger.debug(f"moving to XtalSnapshot to take a screenshot of the sample")
|
||||
self.__set_state(BeamlineStateEnum.XtalSnapshot)
|
||||
time.sleep(0.1)
|
||||
self.save_screenshot_db(sample_id, f"{sample_id}_post_raster_{request.omega_deg}deg")
|
||||
self.__aare.ingest_gridscan(
|
||||
sample=self.sample,
|
||||
@@ -1115,6 +1381,17 @@ class AareDAQ:
|
||||
event_type=SampleEventType.RASTERED,
|
||||
comment=f"Raster completed at {request.omega_deg} deg"
|
||||
)
|
||||
|
||||
logger.info(
|
||||
"Raster finished",
|
||||
extra={
|
||||
"file_prefix": request.file_prefix,
|
||||
"omega_deg": request.omega_deg,
|
||||
"scan_result_is_none": scan_result is None,
|
||||
"sample_id": sample_id,
|
||||
},
|
||||
)
|
||||
|
||||
return CompletedRasterGridElem(
|
||||
request=copy.deepcopy(request),
|
||||
result=scan_result,
|
||||
@@ -1122,7 +1399,18 @@ class AareDAQ:
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(f"Failed during raster: {e}")
|
||||
logger.exception(
|
||||
"Failed during raster",
|
||||
extra={
|
||||
"file_prefix": request.file_prefix,
|
||||
"omega_deg": request.omega_deg,
|
||||
"n_x": request.n_x,
|
||||
"n_y": request.n_y,
|
||||
"exp_time_s": request.exp_time_s,
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
"sample_name": getattr(self.sample, "sample_name", None),
|
||||
},
|
||||
)
|
||||
raise
|
||||
|
||||
def measure_raster(self, r: RasterGridRequest, auto_center: bool) -> CompletedRasterGrid:
|
||||
@@ -1155,6 +1443,9 @@ class AareDAQ:
|
||||
status = self.status
|
||||
|
||||
#self.__aare.create_rotation_run(self.sample, request, status)
|
||||
if request.exp_time_s < 0.004:
|
||||
logger.warning("Exposure time too short for PXII rotation scan")
|
||||
request.exp_time_s = 0.004
|
||||
total_time = request.exp_time_s * request.steps
|
||||
if self.sample is not None and self.sample.db_id is not None:
|
||||
self.__aare.create_rotation_run(self.sample, request, status)
|
||||
@@ -1197,10 +1488,13 @@ class AareDAQ:
|
||||
|
||||
if self.__cfg.simulated_detector:
|
||||
logger.warning("Detector in simulation mode, returning fake zero rotation result.")
|
||||
result = self._build_fake_rotation_result(request)
|
||||
return self._build_fake_rotation_result(request)
|
||||
else:
|
||||
# Let JFJochCommunicationError propagate
|
||||
result = self.__jfjoch.wait_till_done(60)
|
||||
scan_result = self.__jfjoch.wait_till_done(60)
|
||||
return CompletedRotationScan(
|
||||
request=copy.deepcopy(request),
|
||||
result=scan_result,
|
||||
)
|
||||
|
||||
except JFJochCommunicationError as e:
|
||||
logger.error(f"Exception during rotation scan related to JFJoch: {e}")
|
||||
@@ -1209,8 +1503,6 @@ class AareDAQ:
|
||||
logger.error(f"Exception during rotation scan: {e}")
|
||||
raise
|
||||
|
||||
return result
|
||||
|
||||
def measure_rotation(self, request: RotationScanRequest) -> CompletedRotationScan:
|
||||
"""
|
||||
Execute a rotation scan.
|
||||
@@ -1222,7 +1514,22 @@ class AareDAQ:
|
||||
CompletedRotationScan result.
|
||||
"""
|
||||
total_time = request.exp_time_s * request.steps
|
||||
logger.info(f"received rotation scan request: {request}, total time: {total_time}s, steps: {request.steps}")
|
||||
logger.info(
|
||||
"Received rotation scan request",
|
||||
extra={
|
||||
"file_prefix": request.file_prefix,
|
||||
"start_omega_deg": request.start_omega_deg,
|
||||
"dtz": request.dtz,
|
||||
"exp_time_s": request.exp_time_s,
|
||||
"incr_omega_deg": request.incr_omega_deg,
|
||||
"steps": request.steps,
|
||||
"transmission": request.transmission,
|
||||
"screening": getattr(request, "screening", None),
|
||||
"sample_id": getattr(self.sample, "db_id", None),
|
||||
"sample_name": getattr(self.sample, "sample_name", None),
|
||||
"total_time_s": total_time,
|
||||
},
|
||||
)
|
||||
self.__cfg.try_set_busy(timeout=ceil(total_time + 360))
|
||||
|
||||
try:
|
||||
@@ -1345,6 +1652,14 @@ class AareDAQ:
|
||||
)
|
||||
|
||||
if m is None:
|
||||
logger.warning(
|
||||
"ML bounding box returned no detection",
|
||||
extra={
|
||||
"sample_id": sample_id,
|
||||
"ml_image_name": filename,
|
||||
"target_point": prediction_result.target_point,
|
||||
},
|
||||
)
|
||||
if filename is not None and bundle_image is not None:
|
||||
self.__aare.upload_image(sample_id, f"{filename}_no_detection", bundle_image)
|
||||
return None
|
||||
@@ -1356,12 +1671,45 @@ class AareDAQ:
|
||||
self.__aare.upload_image(sample_id, filename, upload_image)
|
||||
|
||||
geom = self.sample_geometry
|
||||
logger.info(
|
||||
"ML bounding box selected",
|
||||
extra={
|
||||
"sample_id": sample_id,
|
||||
"ml_image_name": filename,
|
||||
"omega_deg": geom.omega_deg,
|
||||
"beam_x_pxl": geom.beam_location_pxl.x,
|
||||
"beam_y_pxl": geom.beam_location_pxl.y,
|
||||
"pixel_in_mm": geom.pixel_in_mm,
|
||||
"box_x1": x1,
|
||||
"box_y1": y1,
|
||||
"box_x2": x2,
|
||||
"box_y2": y2,
|
||||
"target_point": prediction_result.target_point,
|
||||
},
|
||||
)
|
||||
|
||||
start_coord = geom.picture_to_smargon(Coordinate(x=x1, y=y1))
|
||||
grid_size = Coordinate(x=geom.beam_size_mm.x * 0.8, y=geom.beam_size_mm.y * 0.8)
|
||||
n_x = max(1, abs(ceil((x2 - x1) * geom.pixel_in_mm / grid_size.x)))
|
||||
n_y = max(1, abs(ceil((y2 - y1) * geom.pixel_in_mm / grid_size.y)))
|
||||
|
||||
logger.info(
|
||||
"Converted ML bounding box to raster request",
|
||||
extra={
|
||||
"sample_id": sample_id,
|
||||
"ml_image_name": filename,
|
||||
"start_sh_x_mm": start_coord.x,
|
||||
"start_sh_y_mm": start_coord.y,
|
||||
"start_sh_z_mm": start_coord.z,
|
||||
"grid_size_x_mm": grid_size.x,
|
||||
"grid_size_y_mm": grid_size.y,
|
||||
"n_x": n_x,
|
||||
"n_y": n_y,
|
||||
"smargon_phi_deg": geom.smargon.phi_deg,
|
||||
"smargon_chi_deg": geom.smargon.chi_deg,
|
||||
},
|
||||
)
|
||||
|
||||
return RasterGridRequest(
|
||||
exp_time_s=0.02,
|
||||
transmission=1.0,
|
||||
|
||||
@@ -10,7 +10,7 @@ from aare.gui.widgets.raster_grid_table import RasterGridTable
|
||||
from aare.common.logger_config import setup_logger
|
||||
|
||||
logger = setup_logger("aareGUI")
|
||||
|
||||
#TODO prevent raster if no grid, or at least rpevent smargon from doing danngerous move to 0,0,0!!!
|
||||
class RasterDataCollectionPanel(ScanSettingsPanel):
|
||||
grid_size_updated = Signal(float, float)
|
||||
exp_time_updated = Signal(float)
|
||||
|
||||
@@ -92,7 +92,7 @@ class RotationDataCollectionPanel(ScanSettingsPanel):
|
||||
self.image_angle = CheckedLineEdit(0, 10.0, 0.2, decimals=3, parent=self)
|
||||
self._layout.addWidget(self.image_angle, 11, 1, 1, 3)
|
||||
self._layout.addWidget(QLabel("°", parent=self), 11, 4)
|
||||
|
||||
#TODO add protection on X10SA to prevent too short exposure time/ too high detector rep rate
|
||||
self._layout.addWidget(QLabel("Image time", parent=self), 12, 0)
|
||||
self.image_time_enter = CheckedLineEdit(
|
||||
0.0005, 10.0, 0.01, decimals=4, parent=self
|
||||
|
||||
@@ -400,11 +400,7 @@ class RasterGridManager(QObject):
|
||||
n_x=ag.n_x,
|
||||
n_y=ag.n_y,
|
||||
grid_size_mm=Coordinate(x=ag.grid_size_mm.x, y=ag.grid_size_mm.y),
|
||||
smargon_top_left=SmargonCoordinate(
|
||||
sh_mm=Coordinate(x=ag.smargon_top_left.sh_mm.x, y=ag.smargon_top_left.sh_mm.y, z=ag.smargon_top_left.sh_mm.z),
|
||||
phi_deg=ag.smargon_top_left.phi_deg,
|
||||
chi_deg=ag.smargon_top_left.chi_deg,
|
||||
),
|
||||
smargon_top_left=None,
|
||||
omega_deg=ag.omega_deg,
|
||||
visible=ag.visible,
|
||||
)
|
||||
@@ -652,7 +648,8 @@ class RasterGridManager(QObject):
|
||||
painter.setBrush(Qt.BrushStyle.NoBrush)
|
||||
painter.drawRect(bounds)
|
||||
|
||||
painter.restor
|
||||
painter.restore()
|
||||
return True
|
||||
|
||||
def _block_value(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user