From 91fcce1ad041dd8e66833af91c9f0af5d7cd9817 Mon Sep 17 00:00:00 2001 From: Dan Hatton Date: Tue, 4 Aug 2026 11:12:23 +0100 Subject: [PATCH 1/2] the ispyb insert function for foil holes mutates the data so the smartem insert needs to happen first as we want the foil hole positions on the full res image for that preferrably we would untangle this a bit in the future so there is no implicit mutation of the data --- .../workflows/spa/flush_spa_preprocess.py | 108 +++++++++--------- 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/src/murfey/workflows/spa/flush_spa_preprocess.py b/src/murfey/workflows/spa/flush_spa_preprocess.py index f3b69073e..1a26b4172 100644 --- a/src/murfey/workflows/spa/flush_spa_preprocess.py +++ b/src/murfey/workflows/spa/flush_spa_preprocess.py @@ -252,6 +252,61 @@ def register_foil_hole( .where(FoilHole.grid_square_id == gsid) .where(FoilHole.session_id == session_id) ).all() + + fh_smartem_uuid = None + + # do this first as the data gets mutated by the ispyb insert function + if SMARTEM_ACTIVE and gs.smartem_uuid: + try: + murfey_session = murfey_db.exec( + select(MurfeySession).where(MurfeySession.id == session_id) + ).one() + machine_config = get_machine_config( + instrument_name=murfey_session.instrument_name + )[murfey_session.instrument_name] + if machine_config.smartem_api_url: + smartem_client = SmartEMAPIClient( + base_url=machine_config.smartem_api_url, logger=logger + ) + fh_data = SmartEMFoilHoleData( + id=str(foil_hole_params.name), + gridsquare_id=str(gs.name), + gridsquare_uuid=gs.smartem_uuid, + x_location=( + int(foil_hole_params.x_location) + if foil_hole_params.x_location is not None + else None + ), + y_location=( + int(foil_hole_params.y_location) + if foil_hole_params.y_location is not None + else None + ), + x_stage_position=foil_hole_params.x_stage_position, + y_stage_position=foil_hole_params.y_stage_position, + diameter=( + int(foil_hole_params.diameter) + if foil_hole_params.diameter is not None + else None + ), + **( + {"uuid": foil_hole_query[0].smartem_uuid} + if foil_hole_query and foil_hole_query[0].smartem_uuid + else {} + ), + ) + if foil_hole_query and foil_hole_query[0].smartem_uuid: + smartem_client.update_foilhole(fh_data) + fh_smartem_uuid = foil_hole_query[0].smartem_uuid + else: + responses = smartem_client.create_gridsquare_foilholes( + gs.smartem_uuid, [fh_data] + ) + if responses: + fh_smartem_uuid = responses[0].uuid + except Exception: + logger.warning("Failed to register foil hole with smartem", exc_info=True) + if foil_hole_query: # Foil hole already exists in the murfey database foil_hole = foil_hole_query[0] @@ -311,61 +366,10 @@ def register_foil_hole( image=str(secured_foil_hole_image_path), ) fh_id = foil_hole.id + foil_hole.smartem_uuid = fh_smartem_uuid murfey_db.add(foil_hole) murfey_db.commit() - if SMARTEM_ACTIVE and gs.smartem_uuid: - try: - murfey_session = murfey_db.exec( - select(MurfeySession).where(MurfeySession.id == session_id) - ).one() - machine_config = get_machine_config( - instrument_name=murfey_session.instrument_name - )[murfey_session.instrument_name] - if machine_config.smartem_api_url: - smartem_client = SmartEMAPIClient( - base_url=machine_config.smartem_api_url, logger=logger - ) - fh_data = SmartEMFoilHoleData( - id=str(foil_hole_params.name), - gridsquare_id=str(gs.name), - gridsquare_uuid=gs.smartem_uuid, - x_location=( - int(foil_hole_params.x_location) - if foil_hole_params.x_location is not None - else None - ), - y_location=( - int(foil_hole_params.y_location) - if foil_hole_params.y_location is not None - else None - ), - x_stage_position=foil_hole_params.x_stage_position, - y_stage_position=foil_hole_params.y_stage_position, - diameter=( - int(foil_hole_params.diameter) - if foil_hole_params.diameter is not None - else None - ), - **( - {"uuid": foil_hole.smartem_uuid} - if foil_hole.smartem_uuid - else {} - ), - ) - if foil_hole.smartem_uuid: - smartem_client.update_foilhole(fh_data) - else: - responses = smartem_client.create_gridsquare_foilholes( - gs.smartem_uuid, [fh_data] - ) - if responses: - foil_hole.smartem_uuid = responses[0].uuid - murfey_db.add(foil_hole) - murfey_db.commit() - except Exception: - logger.warning("Failed to register foil hole with smartem", exc_info=True) - murfey_db.close() return fh_id From 8770d8c9fa2deb63e8db8387295e8c0c314cf0c8 Mon Sep 17 00:00:00 2001 From: Dan Hatton Date: Tue, 4 Aug 2026 11:22:08 +0100 Subject: [PATCH 2/2] stop mutation of foil hole data in ispyb insert function --- src/murfey/server/ispyb.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/murfey/server/ispyb.py b/src/murfey/server/ispyb.py index eead79075..f3ccb777c 100644 --- a/src/murfey/server/ispyb.py +++ b/src/murfey/server/ispyb.py @@ -335,27 +335,31 @@ def do_insert_foil_hole( scale_factor: Optional[float], foil_hole_parameters: FoilHoleParameters, ): + pixel_size = foil_hole_parameters.pixel_size + diameter = foil_hole_parameters.diameter + x_location = foil_hole_parameters.x_location + y_location = foil_hole_parameters.y_location if ( foil_hole_parameters.thumbnail_size_x is not None and foil_hole_parameters.readout_area_x is not None - and foil_hole_parameters.pixel_size is not None + and pixel_size is not None ): - foil_hole_parameters.pixel_size *= ( + pixel_size *= ( foil_hole_parameters.readout_area_x / foil_hole_parameters.thumbnail_size_x ) if scale_factor: - foil_hole_parameters.diameter = ( + diameter = ( int(foil_hole_parameters.diameter * scale_factor) if foil_hole_parameters.diameter else None ) - foil_hole_parameters.x_location = ( + x_location = ( int(foil_hole_parameters.x_location * scale_factor) if foil_hole_parameters.x_location else None ) - foil_hole_parameters.y_location = ( + y_location = ( int(foil_hole_parameters.y_location * scale_factor) if foil_hole_parameters.y_location else None @@ -364,12 +368,12 @@ def do_insert_foil_hole( gridSquareId=grid_square_id, foilHoleLabel=foil_hole_parameters.name, foilHoleImage=foil_hole_parameters.image, - pixelLocationX=foil_hole_parameters.x_location, - pixelLocationY=foil_hole_parameters.y_location, - diameter=foil_hole_parameters.diameter, + pixelLocationX=x_location, + pixelLocationY=y_location, + diameter=diameter, stageLocationX=foil_hole_parameters.x_stage_position, stageLocationY=foil_hole_parameters.y_stage_position, - pixelSize=foil_hole_parameters.pixel_size, + pixelSize=pixel_size, ) try: with ISPyBSession() as db: