End operation after error #98

Merged
perl_d merged 4 commits from end_operation_after_error into master 2026-07-09 14:53:59 +02:00
4 changed files with 17 additions and 49 deletions
+15 -3
View File
@@ -67,6 +67,7 @@ from aarecommon.models.rotation_scan import CompletedRotationScan, RotationScanR
from aarecommon.models.tell import TellPhaseEnum, TellStateModel
from aareDB import SampleEventType
from aare.common.models import DAQOperation
from aare.daq import workflows
from aare.daq.aaredb import AareWrapper
from aare.daq.config import ABR_POS_MOUNT, BeamlineConfig, BeamlineStateEnum
@@ -2598,7 +2599,7 @@ class AareDAQ:
def _end_operation(
self,
start,
start: float,
operation: Optional[DAQOperation] = DAQOperation.AUTOMATION,
error: bool = False,
) -> float:
@@ -2840,9 +2841,11 @@ class AareDAQ:
self._validate_automation_state(context="automation end")
except BECCommunicationError as e:
self._end_operation(start, operation=DAQOperation.AUTOMATION, error=True)
self._raise_if_critical_bec_error(e, command=getattr(e, "operation", None) or "bec")
except JFJochCommunicationError as e:
self._end_operation(start, operation=DAQOperation.AUTOMATION, error=True)
self._raise_if_critical_jfjoch_detector_error(e, command=e.endpoint or "unknown")
raise
@@ -2871,6 +2874,7 @@ class AareDAQ:
error=e,
event_type=SampleEventType.FAILED,
)
self._end_operation(start, operation=DAQOperation.AUTOMATION, error=True)
raise
except (BeamlineBusyTimeoutException, BeamlineBusyException) as e:
@@ -2905,9 +2909,17 @@ class AareDAQ:
error=e,
event_type=SampleEventType.FAILED,
)
self._end_operation(start, operation=None, error=True)
raise
except MountingFailed as e:
logger.error(f"Failed to mount sample: {e}")
if e.critical:
self._end_operation(start, operation=DAQOperation.AUTOMATION, error=True)
raise e
else:
pass
except Exception as e:
logger.error(f"Error in measure: {e}")
if progress.current_step is not None:
@@ -2929,7 +2941,7 @@ class AareDAQ:
error=e,
event_type=SampleEventType.FAILED,
)
self._end_operation(start, operation=DAQOperation.AUTOMATION, error=True)
raise Exception(f"Critical Error in automation: {e}") from e
self._record_completed_sample_time(progress, time.time() - sample_started_at)
+2
View File
@@ -197,6 +197,8 @@ class BeamlineDevices:
@property
def flux(self) -> float:
# TODO FLUX
if self._beamline == MXBeamline.X10SA:
return self.bec_worker.get_flux_x10sa()
return self.transmission * self.full_flux
@property
-36
View File
@@ -1009,27 +1009,6 @@ async def shutter(val: bool, token: str = Depends(oauth2_scheme)):
return "OK"
@app.get("/beamline/image")
async def get_image(token: str = Depends(oauth2_scheme)):
"""
Get the current camera image as a JPEG stream.
Args:
token: OAuth2 access token.
Returns:
StreamingResponse containing the JPEG image.
"""
auth.check_jwt_ro(cfg, auth.parse_token(token))
_, encoded_image = cv2.imencode(".jpg", daq.camera_image) # Encodes the image in JPEG format
image_bytes = io.BytesIO(
encoded_image.tobytes()
) # Convert OpenCV byte format to a file-like object
return StreamingResponse(image_bytes, media_type="image/jpeg")
# TELL procedures
@app.get("/sample/curr_sample")
async def sample(token: str = Depends(oauth2_scheme)) -> SampleShortInfo:
@@ -2546,21 +2525,6 @@ async def send_message_db(
return "OK"
@app.get("/camera/source")
async def get_camera_source(token: str = Depends(oauth2_scheme)):
"""Get the current camera image source."""
auth.check_jwt_ro(cfg, auth.parse_token(token))
return {"source": daq._AareDAQ__devs.samcam_source}
@app.post("/camera/source")
async def set_camera_source(use_zmq: bool, token: str = Depends(oauth2_scheme)):
"""Set the camera image source preference."""
auth.check_jwt_rw(cfg, auth.parse_token(token))
daq._AareDAQ__devs.set_camera_source(use_zmq)
return {"source": daq._AareDAQ__devs.samcam_source}
@app.post("/state/maintenance")
async def maintenance(token: str = Depends(oauth2_scheme)) -> str:
"""
-10
View File
@@ -74,16 +74,6 @@ def test_login_success(client):
assert response.json() == {"access_token": "fake-access-token", "token_type": "bearer"}
def test_get_image(client, mock_backend):
mock_daq = mock_backend["daq"]
mock_daq.camera_image = np.zeros((100, 100, 3), dtype=np.uint8)
response = client.get("/beamline/image", headers={"Authorization": "Bearer fake-token"})
assert response.status_code == 200
assert response.headers["content-type"] == "image/jpeg"
assert len(response.content) > 0
def test_mount_returns_tell_exception_when_mount_precheck_fails(client, mock_backend, monkeypatch):
from aarecommon.errors.exception_handler import TellCommunicationError