From 95e3ecbcea1fdeb6214ea8f39a15a080215f61d2 Mon Sep 17 00:00:00 2001 From: appleb_m Date: Fri, 29 May 2026 10:07:40 +0200 Subject: [PATCH] refactor of send_sample_event --- src/aare/daq/daq.py | 59 +++++++++++---------- src/aare/daq/operations/mounting/service.py | 18 ++----- src/aare/daq/operations/raster/service.py | 6 +-- src/aare/daq/server.py | 14 ++++- 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/src/aare/daq/daq.py b/src/aare/daq/daq.py index 42d40271..1491bbef 100644 --- a/src/aare/daq/daq.py +++ b/src/aare/daq/daq.py @@ -779,7 +779,7 @@ class AareDAQ: }, ) - if sample is None: + if sample is None or sample_id is None: logger.error(f"Error in {operation.value}: {error}") return @@ -789,8 +789,8 @@ class AareDAQ: try: self.__aare.send_sample_event( - sample, - event_type, + sample_id=sample_id, + event_type=event_type, comment=comment, ) except Exception as db_error: @@ -831,12 +831,12 @@ class AareDAQ: logger.warning(f"Failed to reconcile previous sample from TELL before mount: {sync_error}") if previous_sample is not None and previous_sample.db_id is not None: - self.__aare.send_sample_event(previous_sample, SampleEventType.UNMOUNTING) + self.__aare.send_sample_event(previous_sample.db_id, SampleEventType.UNMOUNTING) self.__set_state(BeamlineStateEnum.RobotSampleExchange) if sample is not None and sample.db_id is not None: - self.__aare.send_sample_event(sample, SampleEventType.MOUNTING) + self.__aare.send_sample_event(sample.db_id, SampleEventType.MOUNTING) mounting_result: MountingResult = self._create_mounting_service().execute(target=sample) @@ -853,12 +853,12 @@ class AareDAQ: and previous_sample is not None and previous_sample.db_id is not None ): - self.__aare.send_sample_event(previous_sample, SampleEventType.UNMOUNTED) + self.__aare.send_sample_event(previous_sample.db_id, SampleEventType.UNMOUNTED) self.__set_state(BeamlineStateEnum.SampleAlignment) if mounted_sample is not None and mounted_sample.db_id is not None: - self.__aare.send_sample_event(mounted_sample, SampleEventType.MOUNTED) + self.__aare.send_sample_event(mounted_sample.db_id, SampleEventType.MOUNTED) self.save_screenshot_db(mounted_sample.db_id, f"{mounted_sample.db_id}_mounted") return True @@ -891,7 +891,7 @@ class AareDAQ: ) self.__cfg.current_sample = None self.__aare.send_sample_event( - previous_sample, + previous_sample.db_id, SampleEventType.UNMOUNTED, comment="Auto-unmount succeeded before mount failed", ) @@ -928,7 +928,7 @@ class AareDAQ: self.__devs.lamp_light = 2.5 try: - self.__aare.send_sample_event(sample, SampleEventType.CENTERING) + self.__aare.send_sample_event(sample.db_id, SampleEventType.CENTERING) service = self._create_loop_centering_service() result = service.run(sample_id=sample.db_id) @@ -944,7 +944,7 @@ class AareDAQ: return False self.save_screenshot_db(sample.db_id, "loop_centering") - self.__aare.send_sample_event(sample, SampleEventType.CENTERED) + self.__aare.send_sample_event(sample.db_id, SampleEventType.CENTERED) return True except Exception as e: @@ -966,6 +966,7 @@ class AareDAQ: step_size: int = 15, face_min_ratio: float = 0.3, report_error: bool = True, + sample: Optional[SampleShortInfo] = None, ) -> FaceDetectionResult: """ Execute face detection sequence through the face detection service. @@ -977,14 +978,17 @@ class AareDAQ: result: FaceDetectionResult | None = None try: - try: - sample = self.sample - except Exception: - sample = None + if sample is None: + try: + sample = self.sample + logger.debug(f"No sample provided, using current sample from DAQ {sample}") + except Exception: + logger.error("Failed to get current sample") + sample = None aare = getattr(self, "_AareDAQ__aare", None) - if aare is not None: - aare.send_sample_event(sample, SampleEventType.LOOPFACEDETECTING) + if aare is not None and sample is not None and sample.db_id is not None: + aare.send_sample_event(sample.db_id, SampleEventType.LOOPFACEDETECTING) result = self._create_face_detection_service().run( steps=steps, @@ -1004,7 +1008,7 @@ class AareDAQ: return result if aare is not None: - aare.send_sample_event(sample, SampleEventType.LOOPFACEDETECTED) + aare.send_sample_event(sample.db_id, SampleEventType.LOOPFACEDETECTED) return result except Exception as e: @@ -1109,7 +1113,7 @@ class AareDAQ: ) else: if self.sample is not None and self.sample.db_id is not None: - self.__aare.send_sample_event(self.sample, SampleEventType.RASTERINGFAILED) + self.__aare.send_sample_event(self.sample.db_id, SampleEventType.RASTERINGFAILED) logger.error( "Raster sequence returned no result", extra=merge_log_context( @@ -1198,14 +1202,14 @@ 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.__aare.send_sample_event(self.sample.db_id, 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: self.save_screenshot_db(self.sample.db_id, "scan_preview") - self.__aare.send_sample_event(self.sample, SampleEventType.COLLECTED) + self.__aare.send_sample_event(self.sample.db_id, SampleEventType.COLLECTED) self.__aare.ingest_scan(sample=self.sample, result=result.result, geom=self.sample_geometry, beam_mark_pxl=self.__cfg.get_beam_mark(self.zoom)) return result @@ -2160,6 +2164,9 @@ class AareDAQ: default_message=self._default_screenshot_message(sample.db_id), ) + def send_message_db(self, db_id:int, event_type:SampleEventType, comment: Optional[str] = None): + self.__aare.send_sample_event(db_id, event_type, comment) + @property def sample_spreadsheet(self) -> SampleShortInfoList: return self.__cfg.spreadsheet @@ -2712,14 +2719,8 @@ class AareDAQ: f"Changing state to maintenance due to error: {e}", extra={"from_state": curr_state, "to_state": target}, ) - try: - workflows.common2maintenance(self.__devs, self.__cfg) - logger.info("in BEC mainteance") - except Exception as e2: - logger.error(f"failed to go to BEC Maintenance state, motor positions unknown. {e2}") - finally: - self.__cfg.state = BeamlineStateEnum.Maintenance - self.__cfg.state_busy = False + self.__cfg.state = BeamlineStateEnum.Maintenance + self.__cfg.state_busy = False raise StateTransitionFailed( f"State transition failed: {curr_state} -> {target}. " f"Beamline moved to Maintenance. Original error: {e}" @@ -2931,7 +2932,7 @@ class AareDAQ: ) except Exception as e: - logger.exception(f"Failed to retrieve DAQ status: {e}") + logger.error(f"Failed to retrieve DAQ status: {e}") raise def cancel(self): diff --git a/src/aare/daq/operations/mounting/service.py b/src/aare/daq/operations/mounting/service.py index 3b93c355..7b241353 100644 --- a/src/aare/daq/operations/mounting/service.py +++ b/src/aare/daq/operations/mounting/service.py @@ -6,8 +6,6 @@ from aare.common.exception_handler import ( UnmountingFailed, TellMountFailedException, ) -from aare.common.models import BeamlineStateEnum -from aare.devices.bec_worker import BeamlineState from aare.devices.tell_client import TellEventValueEnum from aare.daq.operations.mounting.models import MountingContext, MountingResult @@ -83,10 +81,6 @@ class MountingService: self.ctx.cfg.record_mount_success() def _mount_handler(self, target) -> None: - if not self.ctx.devs.bec_worker.is_state(BeamlineStateEnum.RobotSampleExchange): - self.logger.error(f"Cannot unmount sample, BEC is not in RobotSampleExchange state") - self.logger.debug(f"Current state: {self.ctx.devs.bec_worker.current_state()}") - self._prepare_mount_hardware() value = self.ctx.devs.tell.mount( @@ -99,6 +93,8 @@ class MountingService: ) if isinstance(value, str): + self.ctx.devs.tell.check_command_ok() + self.logger.error(f"{self.ctx.devs.tell.get_result(self.ctx.devs.tell._last_cmd_id)}") self.logger.error(f"Unexpected string response from Tell mount: {value}") raise CriticalTellException(f"Critical error in TELL mount: unexpected response '{value}'") @@ -130,6 +126,7 @@ class MountingService: raise CriticalTellException(f"Critical error in TELL mount: {message}") def _prepare_mount_hardware(self) -> None: + #self.ctx.devs.tell.check_command_ok() self.ctx.devs.smargon_move_home() self.ctx.devs.aerotech_pos = self.ctx.mount_position self._magnet_position_sensor_check(timeout=360.0) @@ -138,11 +135,6 @@ class MountingService: self.ctx.devs.tell.set_in_mount_position(True) def _unmount_current_sample(self, timeout: float = 60.0): - if not self.ctx.devs.bec_worker.is_state(BeamlineState.ROBOT_SAMPLE_EXCHANGE): - self.logger.error(f"Cannot unmount sample, BEC is not in RobotSampleExchange state") - self.logger.debug(f"Current state: {self.ctx.devs.bec_worker.current_state()}") - - #raise TellMountFailedException(f"Cannot mount sample, BEC is not in RobotSampleExchange state") self._prepare_mount_hardware() previous_sample = self.ctx.cfg.current_sample if previous_sample is not None: @@ -166,10 +158,6 @@ class MountingService: self.ctx.devs.tell.dry(wait=True) def execute(self, *, target) -> MountingResult: - if not self.ctx.devs.bec_worker.is_state(BeamlineState.ROBOT_SAMPLE_EXCHANGE): - self.logger.error(f"Cannot unmount sample, BEC is not in RobotSampleExchange state") - self.logger.debug(f"Current state: {self.ctx.devs.bec_worker.current_state()}") - # raise TellMountFailedException(f"Cannot mount sample, BEC is not in RobotSampleExchange state") previous_sample = self.ctx.cfg.current_sample diff --git a/src/aare/daq/operations/raster/service.py b/src/aare/daq/operations/raster/service.py index 4aca5de3..53204387 100644 --- a/src/aare/daq/operations/raster/service.py +++ b/src/aare/daq/operations/raster/service.py @@ -467,7 +467,7 @@ class RasterService: request=request, ) self.ctx.aare.send_sample_event( - self.ctx.sample, + self.ctx.sample.db_id, event_type=SampleEventType.RASTERED, comment=f"Raster completed at {request.omega_deg:.1f} deg", ) @@ -525,7 +525,7 @@ class RasterService: ) self.ctx.aare.send_sample_event( - sample, + sample.db_id, SampleEventType.RASTERING, comment=f"Raster at {geom.omega_deg:.1f} deg", ) @@ -613,7 +613,7 @@ class RasterService: grid.omega_deg += 90 self.ctx.aare.send_sample_event( - self.ctx.sample, + self.ctx.sample.db_id, SampleEventType.RASTERING, comment=f"Raster at {geom.omega_deg:.1f} deg", ) diff --git a/src/aare/daq/server.py b/src/aare/daq/server.py index a3aeff1d..01d58e79 100644 --- a/src/aare/daq/server.py +++ b/src/aare/daq/server.py @@ -4,11 +4,12 @@ import io import os, time import random from contextlib import asynccontextmanager -from typing import AsyncGenerator +from typing import AsyncGenerator, Optional import json import cv2 import urllib3 import uvicorn +from aareDB import SampleEventType from aare.common.coordinate import AerotechCoordinate from aare.common.auth_models import BatonStatus, BatonRequestStatus @@ -2205,6 +2206,17 @@ async def send_screenshot_db( daq.send_screenshot_db(filename=filename, message=message) return "OK" +async def send_message_db( + db_id: int, + event_type: SampleEventType, + comment: Optional[str] = None, + token: str = Depends(oauth2_scheme), +): + data = auth.parse_token(token) + auth.check_jwt_rw(cfg, data) + daq.send_screenshot_db(db_id=db_id, event_type=event_type, comment=comment) + return "OK" + @app.get("/camera/source") async def get_camera_source(token: str = Depends(oauth2_scheme)): """Get the current camera image source."""