Restructure

This commit is contained in:
2026-01-15 15:34:53 +01:00
parent 2109673d4d
commit 11b5563131
2 changed files with 29 additions and 115 deletions
+24 -113
View File
@@ -1,34 +1,32 @@
import copy
import secrets
import time
from copy import deepcopy
from datetime import datetime
from math import ceil
from typing import List, Tuple, Optional
import cv2
import numpy as np
import redis
import aare.common.face_detection as fd
from aare.daq import workflows
from aare.daq.aaredb import AareWrapper
from aare.daq.autofocus import calculate_focus_measure
from aare.daq.config import BeamlineConfig, aerotech_pos_MOUNT
from aare.daq.config import BeamlineConfig
from aare.daq.config import BeamlineStateEnum
from aare.daq.devices import BeamlineDevices
from aare.daq.mlbox import MlBox
from aare.common.beamline import MXBeamline
from aare.common.coordinate import Coordinate, SmargonCoordinate
from aare.common.diffraction_geometry import DiffractionGeometry
from aare.common.find_xtal import raster_centre_of_mass, create_quality_filtered_array, identify_crystal_raster, \
get_result_list_from_com, get_best_b_factor, get_best_res, get_xtal_size
from aare.common.logger_config import setup_logger
from aare.common.models import (
SampleShortInfo,
PuckLoadedInfo,
SampleShortInfoList,
DAQStatusModel, BeamlineStatus, SessionStatus, SampleCameraSettings, AutofocusSettings, ZoomModeEnum, CrystalSize,
DAQStatusModel, BeamlineStatus, SessionStatus, SampleCameraSettings, ZoomModeEnum,
SimpleScanParameters, MLBoxModel, FluorescenceSpectrumParameterModel,
FluorescenceSpectrumOutputModel)
from aare.common.raster_grid import RasterGridRequest, CompletedRasterGrid, CompletedRasterGridElem
@@ -318,83 +316,14 @@ class AareDAQ:
raise
def __mount_failure_handler(self, mount_error):
failed = self.__cfg.increment_failed_mount_count()
if failed >=4:
#TODO move park does not dry, need to change this!!!
self.__devs.tell.dry(wait=False, wait_cold=-1)
raise CriticalTellException(f"Repeated drying failure, moved to park"
f"\nThere either really is no sample or "
f"a critical failure.\nPlease check the dewar and if a sample, "
f"please contact the MX team")
elif failed >=3:
self.__devs.tell.dry(wait=False, wait_cold=-1)
raise WarningTellException(f"Continued to not find a sample, drying robot in park for 10 minutes. "
f"\n Please get a cup of coffee.\nAfter the robot has dried, "
f"check the sample positions that have been missed, if no samples continue!"
f"\nOtherwise there may be a critical error so please let your local "
f"contact for support")
elif failed == 2:
self.__devs.tell.dry(wait=False)
raise MountingFailed(f"Drying gripper: repeated error: {mount_error}")
else:
raise MountingFailed(f"{mount_error}")
pass
def __mount(self, target: SampleShortInfo | None):
pass
@sample.setter
def sample(self, target: SampleShortInfo | None):
# This will set internally state to SampleExchange, but will return to SampleAlignment
# before exiting
self.__cfg.try_set_busy(timeout=360)
try:
curr_sample = self.__cfg.current_sample
curr_sample_is_manual = False
logger.info(f"current sample: {curr_sample}")
logger.info(f"new target is: {target}")
self.__cfg.crystal_size = CrystalSize(x=0, y=0, z=0)
self.__cfg.last_best_b_factor = None
self.__cfg.last_best_res = None
self.__cfg.xrf = None
if curr_sample is not None and curr_sample.location is None:
self.__cfg.current_sample = None
curr_sample_is_manual = True
if target is not None or not curr_sample_is_manual:
self.__mount(target)
if target is not None and target.db_id is not None:
#self.__aare.sample_mounted(self.__cfg.current_sample)
logger.info(f"post_mount_{target.db_id}_{self.__devs.zoom}")
self.save_screenshot_db(target.db_id , f"post_mount_{target.db_id }_{self.__devs.zoom}")
except Exception as e:
self.__cfg.state_busy = False
# If unmount succeeded, but mount failed
mounted_sample = self.__devs.tell.get_mounted_sample()
#TODO check the following error logic
# if target is not None:
# print(f"TELL: Error mounting, TELL believes current sample is {mounted_sample}, while expected {target.location}")
if mounted_sample is None:
logger.error("TELL: After mounting there is no sample on gonio according to TELL")
self.__cfg.current_sample = None
if target is not None:
raise e
elif target is not None and (target.location is not None
and mounted_sample.puck.pos == target.location.pos
and mounted_sample.puck.segment == target.location.segment
and mounted_sample.pin == target.pin):
logger.info("TELL: Actually mounting was correct according to TELL, so setting current sample to target")
self.__cfg.current_sample = target
else:
raise e
self.__set_state(BeamlineStateEnum.SampleAlignment)
self.__cfg.state_busy = False
#if target is not None and target.location is not None:
# self.__loop_center_sequence(target.db_id)
pass
@property
def camera_image(self) -> np.ndarray | None:
@@ -514,7 +443,6 @@ class AareDAQ:
bgr_array = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
cv2.imwrite(f"bkg{zoom_value:.0f}_{exposure*1000:.0f}_{gain:.0f}.jpg", bgr_array)
self.__cfg.state_busy = False
self.__devs.sample_cam.set_auto()
except Exception as e:
self.__cfg.state_busy = False
raise e
@@ -754,8 +682,8 @@ class AareDAQ:
if beam_y !=0 and abs(centre_y-beam_y)/abs(beam_y) > tolerance:
coord = geom.picture_to_smargon(Coordinate(x=beam_x, y=centre_y))
self.__devs.smargon.target = SmargonCoordinate(sh_mm=coord)
self.__devs.smargon.wait(60)
self.__devs.smargon = SmargonCoordinate(sh_mm=coord)
self.__devs.smargon_wait(60)
return
@@ -771,10 +699,10 @@ class AareDAQ:
self.__devs.samcam_settings = SampleCameraSettings(
exposure=zoom_settings[zoom_value].exposure,
gain=zoom_settings[zoom_value].gain)
self.__devs.zoom_sync(zoom_value)
self.__devs.set_zoom(zoom_value, wait=True)
boxes: dict[int, tuple[float, float, float, float]] = {}
curr_angle = int(self.__devs.aerotech.omega)
curr_angle = int(self.__devs.aerotech_omega)
total_range = steps * step_size + 1
start_angle = curr_angle if curr_angle + total_range < 720 else 0
end_angle = curr_angle + total_range
@@ -782,7 +710,7 @@ class AareDAQ:
for angle in range(start_angle, end_angle, step_size):
logger.debug(f'moving to angle: {angle}')
rotate_time = time.perf_counter()
self.__devs.aerotech.move(angle, wait=True)
self.__devs.aerotech_omega = angle
logger.info(f"time to rotate 15 degrees: {time.perf_counter() - rotate_time}")
curr_image = cv2.cvtColor(self.camera_image, cv2.COLOR_RGB2BGR)
@@ -818,7 +746,7 @@ class AareDAQ:
logger.info(f"best params: {best_params}")
logger.info(f"chosen fit: {best_name}")
logger.info(f"best angle: {flat_face_angle}")
self.__devs.aerotech.move(flat_face_angle, wait=True)
self.__devs.aerotech_omega = flat_face_angle
samples_out = fd.get_samples_out(boxes)
logger.info(f"face detection sequence done, samples: {samples_out}")
@@ -864,7 +792,7 @@ class AareDAQ:
self.__devs.samcam_settings = SampleCameraSettings(exposure=exposure, gain=gain)
exp = int(exposure * 1000)
gn = int(gain)
self.__devs.zoom_sync(zoom_value)
self.__devs.set_zoom(zoom_value, wait=True)
logger.debug(f'zoom={zoom_value},gain={gn}, exp={exp}ms')
found_flag = False
@@ -874,7 +802,7 @@ class AareDAQ:
for angle in base_angles:
logger.debug(f"Moving to new omega: {angle}")
time_to_move_aerotech= time.perf_counter()
self.__devs.aerotech.move(angle, wait=True)
self.__devs.aerotech_omega = angle
logger.info(f"time to move: {time.perf_counter()-time_to_move_aerotech}")
filename = f"{sample_id}_{angle}_{zoom_value:.0f}_{exp}_{gn}" if sample_id is not None else None
@@ -901,8 +829,8 @@ class AareDAQ:
found_angle = angle
time_to_move_smargon = time.perf_counter()
self.__devs.smargon.target = target
self.__devs.smargon.wait(60)
self.__devs.smargon_pos = target
self.__devs.smargon_wait(60)
logger.info(f"time to move smargon: {time.perf_counter() - time_to_move_smargon}")
if targets_found_this_attempt == 0:
@@ -1128,7 +1056,7 @@ class AareDAQ:
self.__cfg.zoom_mode = ZoomModeEnum.User
self.__devs.samcam_settings = self.__cfg.zoom_settings.get_camera_settings(self.zoom)
self.__devs.dtz.move(params.dtz, wait=True)
self.__devs.dtz = params.dtz
if self.omega + 180 < 720:
start_omega = self.omega
else:
@@ -1288,7 +1216,7 @@ class AareDAQ:
flux_ph_s=self.__devs.full_flux,
sample_camera=self.__devs.samcam_settings,
name=self.__bl,
transmission=self.__devs.transmission.get(),
transmission=self.__devs.transmission,
zoom=self.__devs.zoom,
commissioning_mode=self.__cfg.commissioning_mode,
dtz_min=self.__devs.dtz_low,
@@ -1314,7 +1242,7 @@ class AareDAQ:
def cancel(self):
if self.__cfg.state == BeamlineStateEnum.DataCollection:
self.__devs.aerotech.stop()
self.__devs.aerotech_stop()
self.__jfjoch.cancel()
def anneal(self, time_s: float):
@@ -1331,12 +1259,12 @@ class AareDAQ:
self.__set_state(BeamlineStateEnum.XrayFluorescence)
if fm.transmission is not None:
self.__devs.transmission.set(fm.transmission, wait=True)
self.__devs.transmission = fm.transmission
self.__devs.fluorimeter.start_acquisition(erase=fm.erase)
self.__devs.aerotech.set_shutter(1)
self.__devs.shutter = True
time.sleep(fm.acq_time_s)
self.__devs.aerotech.set_shutter(0)
self.__devs.shutter = False
self.__devs.fluorimeter.stop_acquisition()
time.sleep(0.2)
spectrum = self.__devs.fluorimeter.get_current_data()
@@ -1358,20 +1286,3 @@ class AareDAQ:
self.__set_state(BeamlineStateEnum.SampleAlignment)
self.__cfg.state_busy = False
raise e
def fluorimeter_start(self, erase: bool = False):
self.__devs.aerotech.set_shutter(1)
self.__devs.fluorimeter.start_acquisition(erase=erase)
def fluorimeter_stop(self):
self.__devs.fluorimeter.stop_acquisition()
self.__devs.aerotech.set_shutter(0)
def fluorimeter_status(self) -> int | None:
return self.__devs.fluorimeter.check_status()
def fluorimeter_data(self):
return self.__devs.fluorimeter.get_current_data()
def fluorimeter_background(self):
return self.__devs.fluorimeter.get_current_background()
+5 -2
View File
@@ -206,6 +206,9 @@ class BeamlineDevices:
def aerotech_lock(self, val: bool):
pass
def aerotech_stop(self):
pass
# Smargon goniometer
@property
def smargon_pos(self) -> SmargonCoordinate:
@@ -218,8 +221,8 @@ class BeamlineDevices:
def smargon_pos(self, pos: SmargonCoordinate):
self.set_smargon_pos(pos, wait=True)
def smargon_wait(self):
self.__smargon.wait()
def smargon_wait(self, timeout: float = 10.0):
self.__smargon.wait(timeout=timeout)
def smargon_move_home(self):
self.__smargon.move_home(wait=True)