Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
759f1e7
Added new Murfey workflow stub for registering FIB milling progress t…
tieneupin Jun 1, 2026
4f4e128
Updated log string to check for
tieneupin Jun 1, 2026
aa9fb1a
Wrong module path in 'pyproject.toml'
tieneupin Jun 1, 2026
d6489fb
Bumped required 'ispyb' version
tieneupin Jun 1, 2026
e976593
Added new TransportManager functinos to insert and update MillingStep…
tieneupin Jun 2, 2026
ec1cb85
Moved 'DataCollectionGroup' and 'GridSquare' to the 'General' section…
tieneupin Jun 2, 2026
fd1493e
Added logic to register FIB milling metadata in ISPyB and Murfey
tieneupin Jun 2, 2026
19cbef9
Merged recent changes from 'main' branch
tieneupin Jun 3, 2026
03227a2
Add field validation logic to convert stringified 'None' into Pythoni…
tieneupin Jun 3, 2026
aba4a52
Bugfixes to the MillingStep insertion logic:
tieneupin Jun 3, 2026
6b57da5
Forgot to add 'classmethod' decorator
tieneupin Jun 3, 2026
b6add3d
Add integrated test for the FIB milling progress workflow
tieneupin Jun 3, 2026
f57a1f5
Updated ISPyB schema version
tieneupin Jun 3, 2026
1218721
Move 'MillingStep' record creation into 'do_insert_milling_step' inst…
tieneupin Jun 3, 2026
82169a5
Simplify lookup logic
tieneupin Jun 3, 2026
6818e08
Add stringified 'None' values as statuses
tieneupin Jun 3, 2026
6047bd2
Centralise early exits under main 'run' function to make testing simpler
tieneupin Jun 4, 2026
eb5b4f9
More stringent checks on the registered database results
tieneupin Jun 4, 2026
bde4246
Missed converting a return statement to a dictionary
tieneupin Jun 4, 2026
b9ed626
Unpacked 'milling_steps' and 'stage_info' sections from the 'site_inf…
tieneupin Jun 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ name: Build and test
on: [push, pull_request]

env:
ISPYB_DATABASE_SCHEMA: 4.11.0
ISPYB_DATABASE_SCHEMA: 5.1.0
# Installs from GitHub
# Versions: https://github.com/DiamondLightSource/ispyb-database/tags
# Previous version(s):
# 4.11.0
# 4.8.0
# 4.2.1 # released 2024-08-19
# 4.1.0 # released 2024-03-26
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ developer = [
server = [
"cryptography",
"graypy",
"ispyb>=10.2.4", # Responsible for setting requirements for SQLAlchemy and mysql-connector-python;
"ispyb>=12.1.0", # Responsible for setting requirements for SQLAlchemy and mysql-connector-python;
"jinja2",
"mrcfile",
"numpy<3",
Expand Down Expand Up @@ -117,6 +117,7 @@ TomographyMetadataContext = "murfey.client.contexts.tomo_metadata:TomographyMeta
"data_collection_group" = "murfey.workflows.register_data_collection_group:run"
"experiment_type_update" = "murfey.workflows.register_experiment_type_update:run"
"fib.register_atlas" = "murfey.workflows.fib.register_atlas:run"
"fib.register_milling_progress" = "murfey.workflows.fib.register_milling_progress:run"
"pato" = "murfey.workflows.notifications:notification_setup"
"picked_particles" = "murfey.workflows.spa.picking:particles_picked"
"picked_tomogram" = "murfey.workflows.tomo.picking:picked_tomogram"
Expand Down
19 changes: 12 additions & 7 deletions src/murfey/server/api/workflow_fib.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import json
import logging
import os
from pathlib import Path
Expand All @@ -7,7 +6,7 @@
import PIL.Image
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from sqlmodel import Session, select
from sqlmodel import select

import murfey.util.db as MurfeyDB
from murfey.server import _transport_object
Expand Down Expand Up @@ -36,7 +35,7 @@ def register_fib_atlas(
fib_atlas: FIBAtlasFile,
):
if _transport_object is None:
logger.error("No Transport Manager object was set up")
logger.error("No TransportManager object was set up")
return None
_transport_object.send(
_transport_object.feedback_queue,
Expand All @@ -52,11 +51,17 @@ def register_fib_atlas(
def register_fib_milling_progress(
session_id: int,
site_info: LamellaSiteInfo,
db: Session = murfey_db,
):
logger.debug(
"Received the following FIB metadata for registration:\n"
f"{json.dumps(site_info.model_dump(exclude_none=True), indent=2, default=str)}"
if _transport_object is None:
logger.error("No TransportManager object was set up")
return None
_transport_object.send(
_transport_object.feedback_queue,
{
"register": "fib.register_milling_progress",
"session_id": session_id,
"site_info": site_info.model_dump(exclude_none=True),
},
)


Expand Down
160 changes: 160 additions & 0 deletions src/murfey/server/ispyb.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
DataCollectionGroup,
FoilHole,
GridSquare,
MillingStep,
MillingStepName,
ProcessingJob,
ProcessingJobParameter,
Proposal,
Expand Down Expand Up @@ -710,6 +712,164 @@ def do_update_processing_status(self, record: AutoProcProgram, **kwargs):
)
return {"success": False, "return_value": None}

def do_insert_milling_step(
self,
# MillingStepName identifiers
recipe_name: str,
activity_name: str,
grid_square_id: int,
# Values
is_enabled: bool | None = None,
status: str | None = None,
execution_time: float | None = None,
stage_x: float | None = None,
stage_y: float | None = None,
stage_z: float | None = None,
rotation: float | None = None,
tilt_alpha: float | None = None,
beam_type: str | None = None,
beam_voltage: float | None = None,
beam_current: float | None = None,
milling_angle: float | None = None,
depth_correction: float | None = None,
lamella_offset: float | None = None,
trench_height_front: float | None = None,
trench_height_rear: float | None = None,
width_overlap_front_left: float | None = None,
width_overlap_front_right: float | None = None,
width_overlap_rear_left: float | None = None,
width_overlap_rear_right: float | None = None,
):
try:
with ISPyBSession() as db:
# Find the ID of this MillingStep
milling_step_name = (
db.query(MillingStepName)
.filter(
MillingStepName.recipe == recipe_name,
MillingStepName.step == activity_name,
)
.one()
)
record = MillingStep(
# IDs
millingStepNameId=milling_step_name.millingStepNameId,
gridSquareId=grid_square_id,
# Values
isEnabled=is_enabled,
status=status,
executionTime=execution_time,
stageX=stage_x,
stageY=stage_y,
stageZ=stage_z,
rotation=rotation,
alphaTilt=tilt_alpha,
beamType=beam_type,
beamVoltage=beam_voltage,
beamCurrent=beam_current,
millingAngle=milling_angle,
depthCorrection=depth_correction,
lamellaOffset=lamella_offset,
trenchHeightFront=trench_height_front,
trenchHeightRear=trench_height_rear,
widthOverlapFrontLeft=width_overlap_front_left,
widthOverlapFrontRight=width_overlap_front_right,
widthOverlapRearLeft=width_overlap_rear_left,
widthOverlapRearRight=width_overlap_rear_right,
)
db.add(record)
db.commit()
log.info(f"Created MillingStep {record.millingStepId}")
return {"success": True, "return_value": record.millingStepId}
except ispyb.ISPyBException as e:
log.error(
"Insert MillingStep entry caused exception '%s'.",
e,
exc_info=True,
)
return {"success": False, "return_value": None}

def do_update_milling_step(
self,
milling_step_id: int,
is_enabled: bool | None = None,
status: str | None = None,
execution_time: float | None = None,
stage_x: float | None = None,
stage_y: float | None = None,
stage_z: float | None = None,
rotation: float | None = None,
tilt_alpha: float | None = None,
beam_type: str | None = None,
beam_voltage: float | None = None,
beam_current: float | None = None,
milling_angle: float | None = None,
depth_correction: float | None = None,
lamella_offset: float | None = None,
trench_height_front: float | None = None,
trench_height_rear: float | None = None,
width_overlap_front_left: float | None = None,
width_overlap_front_right: float | None = None,
width_overlap_rear_left: float | None = None,
width_overlap_rear_right: float | None = None,
):
try:
with ISPyBSession() as db:
milling_step = (
db.query(MillingStep)
.filter(MillingStep.millingStepId == milling_step_id)
.one()
)
milling_step.isEnabled = is_enabled or milling_step.isEnabled
milling_step.status = status or milling_step.status
milling_step.executionTime = (
execution_time or milling_step.executionTime
)
milling_step.stageX = stage_x or milling_step.stageX
milling_step.stageY = stage_y or milling_step.stageY
milling_step.stageZ = stage_z or milling_step.stageZ
milling_step.rotation = rotation or milling_step.rotation
milling_step.alphaTilt = tilt_alpha or milling_step.alphaTilt
milling_step.beamType = beam_type or milling_step.beamType
milling_step.beamVoltage = beam_voltage or milling_step.beamVoltage
milling_step.beamCurrent = beam_current or milling_step.beamCurrent
milling_step.millingAngle = milling_angle or milling_step.millingAngle
milling_step.depthCorrection = (
depth_correction or milling_step.depthCorrection
)
milling_step.lamellaOffset = (
lamella_offset or milling_step.lamellaOffset
)
milling_step.trenchHeightFront = (
trench_height_front or milling_step.trenchHeightFront
)
milling_step.trenchHeightRear = (
trench_height_rear or milling_step.trenchHeightRear
)
milling_step.widthOverlapFrontLeft = (
width_overlap_front_left or milling_step.widthOverlapFrontLeft
)
milling_step.widthOverlapFrontRight = (
width_overlap_front_right or milling_step.widthOverlapFrontRight
)
milling_step.widthOverlapRearLeft = (
width_overlap_rear_left or milling_step.widthOverlapRearLeft
)
milling_step.widthOverlapRearRight = (
width_overlap_rear_right or milling_step.widthOverlapRearRight
)

db.add(milling_step)
db.commit()
return {"success": True, "return_value": milling_step.millingStepId}
except ispyb.ISPyBException as e:
log.error(
"Updating MillingStep entry caused exception '%s'.",
e,
exc_info=True,
)
return {"success": False, "return_value": None}

def do_buffer_lookup(self, app_id: int, uuid: int) -> Optional[int]:
with ISPyBSession() as db:
buffer_objects = (
Expand Down
Loading