From 844aca8d1c307f46239a2f506d59b019fd4bac14 Mon Sep 17 00:00:00 2001 From: yxd92326 Date: Fri, 12 Jun 2026 15:32:33 +0100 Subject: [PATCH 1/2] Read whether a search map is a lamella and request hooks --- src/murfey/client/contexts/tomo_metadata.py | 14 +++++ src/murfey/util/db.py | 57 +++++++++++---------- src/murfey/util/models.py | 23 +++++---- src/murfey/workflows/tomo/tomo_metadata.py | 15 ++++++ 4 files changed, 70 insertions(+), 39 deletions(-) diff --git a/src/murfey/client/contexts/tomo_metadata.py b/src/murfey/client/contexts/tomo_metadata.py index 09f2780d2..6403b6f6d 100644 --- a/src/murfey/client/contexts/tomo_metadata.py +++ b/src/murfey/client/contexts/tomo_metadata.py @@ -150,6 +150,19 @@ def post_transfer( else "" ) + # Read the session dm to find out if this is a lamella search map or not + lamella = None + if source and (source / "Session.dm").is_file(): + with open(source / "Session.dm") as xml: + session_xml = xmltodict.parse(xml.read()) + lamella_workflow = session_xml.get("TomographySession", {}).get( + "LamellaWorkflow", None + ) + if lamella_workflow: + lamella = lamella_workflow == "true" + else: + logger.warning("Cannot find tomography Session.dm file") + capture_post( base_url=str(environment.url.geturl()), router_name="session_control.tomo_router", @@ -168,6 +181,7 @@ def post_transfer( "reference_matrix": ref_matrix, "stage_correction": stage_matrix, "image_shift_correction": image_matrix, + "lamella": lamella, }, ) diff --git a/src/murfey/util/db.py b/src/murfey/util/db.py index eb92f48fa..56b891d78 100644 --- a/src/murfey/util/db.py +++ b/src/murfey/util/db.py @@ -556,41 +556,42 @@ class SearchMap(SQLModel, table=True): # type: ignore session_id: int = Field(foreign_key="session.id") name: str tag: str - x_location: Optional[float] = None - y_location: Optional[float] = None - x_stage_position: Optional[float] = None - y_stage_position: Optional[float] = None - pixel_size: Optional[float] = None + lamella: bool | None = None + x_location: float | None = None + y_location: float | None = None + x_stage_position: float | None = None + y_stage_position: float | None = None + pixel_size: float | None = None image: str = "" - binning: Optional[float] = None - reference_matrix_m11: Optional[float] = None - reference_matrix_m12: Optional[float] = None - reference_matrix_m21: Optional[float] = None - reference_matrix_m22: Optional[float] = None - stage_correction_m11: Optional[float] = None - stage_correction_m12: Optional[float] = None - stage_correction_m21: Optional[float] = None - stage_correction_m22: Optional[float] = None - image_shift_correction_m11: Optional[float] = None - image_shift_correction_m12: Optional[float] = None - image_shift_correction_m21: Optional[float] = None - image_shift_correction_m22: Optional[float] = None - width: Optional[int] = None - height: Optional[int] = None + binning: float | None = None + reference_matrix_m11: float | None = None + reference_matrix_m12: float | None = None + reference_matrix_m21: float | None = None + reference_matrix_m22: float | None = None + stage_correction_m11: float | None = None + stage_correction_m12: float | None = None + stage_correction_m21: float | None = None + stage_correction_m22: float | None = None + image_shift_correction_m11: float | None = None + image_shift_correction_m12: float | None = None + image_shift_correction_m21: float | None = None + image_shift_correction_m22: float | None = None + width: int | None = None + height: int | None = None session: Optional[Session] = Relationship(back_populates="search_maps") tilt_series: List["TiltSeries"] = Relationship( back_populates="search_map", sa_relationship_kwargs={"cascade": "delete"} ) - atlas_id: Optional[int] = Field( + atlas_id: int | None = Field( foreign_key="datacollectiongroup.dataCollectionGroupId" ) - scaled_pixel_size: Optional[float] = None - pixel_location_x: Optional[int] = None - pixel_location_y: Optional[int] = None - scaled_height: Optional[int] = None - scaled_width: Optional[int] = None - angle: Optional[float] = None - quality_indicator: Optional[float] = None + scaled_pixel_size: float | None = None + pixel_location_x: int | None = None + pixel_location_y: int | None = None + scaled_height: int | None = None + scaled_width: int | None = None + angle: float | None = None + quality_indicator: float | None = None data_collection_group: Optional["DataCollectionGroup"] = Relationship( back_populates="search_maps" ) diff --git a/src/murfey/util/models.py b/src/murfey/util/models.py index f2f00fc0e..866e8f9f8 100644 --- a/src/murfey/util/models.py +++ b/src/murfey/util/models.py @@ -317,20 +317,21 @@ class FoilHoleParameters(BaseModel): class SearchMapParameters(BaseModel): tag: str - x_location: Optional[float] = None - y_location: Optional[float] = None - x_stage_position: Optional[float] = None - y_stage_position: Optional[float] = None - pixel_size: Optional[float] = None - image: Optional[str] = None - binning: Optional[float] = None + x_location: float | None = None + y_location: float | None = None + x_stage_position: float | None = None + y_stage_position: float | None = None + pixel_size: float | None = None + image: str | None = None + binning: float | None = None reference_matrix: Dict[str, float] = {} stage_correction: Dict[str, float] = {} image_shift_correction: Dict[str, float] = {} - height: Optional[int] = None - width: Optional[int] = None - height_on_atlas: Optional[int] = None - width_on_atlas: Optional[int] = None + height: int | None = None + width: int | None = None + height_on_atlas: int | None = None + width_on_atlas: int | None = None + lamella: bool | None = None class BatchPositionParameters(BaseModel): diff --git a/src/murfey/workflows/tomo/tomo_metadata.py b/src/murfey/workflows/tomo/tomo_metadata.py index 3ff235fcc..2f79f649e 100644 --- a/src/murfey/workflows/tomo/tomo_metadata.py +++ b/src/murfey/workflows/tomo/tomo_metadata.py @@ -1,4 +1,5 @@ import logging +from importlib.metadata import entry_points import numpy as np from sqlmodel import Session, select @@ -40,6 +41,7 @@ def register_search_map_in_database( if search_map_query: # See if there is already a search map with this name and update if so search_map = search_map_query[0] + search_map.lamella = search_map_params.lamella or search_map.lamella search_map.x_stage_position = ( search_map_params.x_stage_position or search_map.x_stage_position ) @@ -120,6 +122,7 @@ def register_search_map_in_database( name=search_map_name, session_id=session_id, tag=search_map_params.tag, + lamella=search_map_params.lamella, x_stage_position=search_map_params.x_stage_position, y_stage_position=search_map_params.y_stage_position, pixel_size=search_map_params.pixel_size, @@ -243,6 +246,18 @@ def register_search_map_in_database( if close_db: murfey_db.close() + if search_map_hooks := entry_points(group="murfey.hooks", name="search_map"): + try: + for hook in search_map_hooks: + hook.load()( + id=search_map.id, + image=search_map_params.image, + pixel_size=search_map_params.pixel_size, + lamella=search_map_params.lamella, + ) + except Exception as e: + logger.error(f"Call to search map hook failed with {e}", exc_info=True) + def register_batch_position_in_database( session_id: MurfeySessionID, From eee91b5578c5d73d18cd1eb12f5dca811395c9f6 Mon Sep 17 00:00:00 2001 From: yxd92326 Date: Fri, 12 Jun 2026 16:02:07 +0100 Subject: [PATCH 2/2] Rename id field --- src/murfey/workflows/tomo/tomo_metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/murfey/workflows/tomo/tomo_metadata.py b/src/murfey/workflows/tomo/tomo_metadata.py index 2f79f649e..df1b9479e 100644 --- a/src/murfey/workflows/tomo/tomo_metadata.py +++ b/src/murfey/workflows/tomo/tomo_metadata.py @@ -250,7 +250,7 @@ def register_search_map_in_database( try: for hook in search_map_hooks: hook.load()( - id=search_map.id, + ispyb_id=search_map.id, image=search_map_params.image, pixel_size=search_map_params.pixel_size, lamella=search_map_params.lamella,