Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 8 additions & 1 deletion src/murfey/server/api/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,15 @@
from smartem_backend.keycloak_client import KeycloakClient, load_keycloak_config
from smartem_common.schemas import AcquisitionData, MicroscopeData

from murfey.util.config import get_security_config

keycloak_client = KeycloakClient(
load_keycloak_config(Path(os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION") or ""))
load_keycloak_config(
Path(
os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION")
or get_security_config().smartem_keycloak_config
)
)
)
SMARTEM_ACTIVE = True
except ImportError:
Expand Down
57 changes: 45 additions & 12 deletions src/murfey/server/api/session_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@
from fastapi.responses import FileResponse
from ispyb.sqlalchemy import AutoProcProgram as ISPyBAutoProcProgram
from pydantic import BaseModel
from sqlalchemy import func
from sqlalchemy import desc, func
from sqlmodel import select

try:
from smartem_agent.fs_parser import EpuParser
from smartem_backend.api_client import SmartEMAPIClient
from smartem_backend.keycloak_client import KeycloakClient, load_keycloak_config
from smartem_common.schemas import AtlasData
from smartem_common.schemas import AtlasTileGridSquarePositionData

from murfey.util.config import get_security_config

keycloak_client = KeycloakClient(
load_keycloak_config(Path(os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION") or ""))
load_keycloak_config(
Path(
os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION")
or get_security_config().smartem_keycloak_config
)
)
)
SMARTEM_ACTIVE = True
except ImportError:
Expand Down Expand Up @@ -390,12 +398,23 @@ def register_atlas(
keycloak_client=keycloak_client,
)
grid_uuid = None
atlas_path = None
if atlas_registration_data.tag:
dcg = db.exec(
select(DataCollectionGroup)
.where(DataCollectionGroup.session_id == session_id)
.where(DataCollectionGroup.tag == atlas_registration_data.tag)
).one_or_none()
if dcg is None:
sample = int(
atlas_registration_data.tag.split("Sample")[1].split("/")[0]
)
dcg = db.exec(
select(DataCollectionGroup)
.where(DataCollectionGroup.session_id == session_id)
.where(DataCollectionGroup.sample == sample)
.order_by(desc(DataCollectionGroup.id))
).first()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This query could still return nothing, so maybe worth catching that?

grid_uuid = dcg.smartem_grid_uuid
else:
possible_grids = smartem_client.get_acquisition_grids(
Expand All @@ -404,8 +423,9 @@ def register_atlas(
for grid in possible_grids:
if grid.name == atlas_registration_data.name.replace("_atlas", ""):
grid_uuid = grid.uuid
atlas_path = Path(grid.atlas_dir).parent
break
if grid_uuid is not None:
if grid_uuid is not None and atlas_path is not None:
existing_atlas = smartem_client.get_grid_atlas(grid_uuid)
if (
existing_atlas.name == atlas_registration_data.name
Expand All @@ -414,16 +434,29 @@ def register_atlas(
):
# there is a question here of whether the grid should be registered if specified
return
atlas_data = AtlasData(
id=atlas_registration_data.name,
acquisition_date=datetime.now(),
storage_folder=atlas_registration_data.storage_folder,
name=atlas_registration_data.name,
tiles=[],
gridsquare_positions=None,
grid_uuid=grid_uuid,
parser = EpuParser()
atlas_data = parser.parse_atlas_manifest(
str(atlas_path / "Atlas.dm"), grid_uuid
)
atlas_data.acquisition_date = atlas_data.acquisition_date.replace(
tzinfo=None
) # timezone information is not consistently provided so drop it
smartem_client.create_grid_atlas(atlas_data)
registered_squares = smartem_client.get_grid_gridsquares(grid_uuid)
gs_uuid_map = {gs.gridsquare_id: gs.uuid for gs in registered_squares}
for atlastile in atlas_data.tiles:
pos_data_for_tile = []
for gsid, gs_tile_pos in atlastile.gridsquare_positions.items():
for pos in gs_tile_pos:
pos_data_for_tile.append(
AtlasTileGridSquarePositionData(
gridsquare_uuid=gs_uuid_map[gsid],
tile_uuid=atlastile.uuid,
position=pos.position,
size=pos.size,
)
)
smartem_client.link_atlas_tile_and_gridsquares(pos_data_for_tile)
if atlas_registration_data.register_grid:
smartem_client.grid_registered(grid_uuid)
else:
Expand Down
9 changes: 8 additions & 1 deletion src/murfey/server/api/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,15 @@
MicrographManifest as SmartEMMicrographManifest,
)

from murfey.util.config import get_security_config

keycloak_client = KeycloakClient(
load_keycloak_config(Path(os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION") or ""))
load_keycloak_config(
Path(
os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION")
or get_security_config().smartem_keycloak_config
)
)
)
SMARTEM_ACTIVE = True
except ImportError:
Expand Down
3 changes: 3 additions & 0 deletions src/murfey/util/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ class Security(BaseModel):
session_token_timeout: Optional[int] = None
allow_origins: list[str] = ["*"]

# SmartEM keycloak config file
smartem_keycloak_config: str = ""

# RabbitMQ settings
rabbitmq_credentials: Path
feedback_queue: str = "murfey_feedback"
Expand Down
28 changes: 25 additions & 3 deletions src/murfey/workflows/spa/ctf_estimation.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,25 @@
try:
from smartem_backend.api_client import SmartEMAPIClient
from smartem_backend.keycloak_client import KeycloakClient, load_keycloak_config
from smartem_backend.model.http_request import MicrographUpdateRequest
from smartem_backend.model.http_response import MicrographResponse
from smartem_backend.model.http_request import (
CtfEstimationRegisteredRequest,
MicrographUpdateRequest,
)
from smartem_backend.model.http_response import (
MicrographResponse,
ProcessingFeedbackPublishResponse,
)
from smartem_common.entity_status import MicrographStatus

from murfey.util.config import get_security_config

keycloak_client = KeycloakClient(
load_keycloak_config(Path(os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION") or ""))
load_keycloak_config(
Path(
os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION")
or get_security_config().smartem_keycloak_config
)
)
)
SMARTEM_ACTIVE = True
except ImportError:
Expand Down Expand Up @@ -55,6 +68,15 @@ def ctf_estimated(message: dict, murfey_db: Session) -> dict[str, bool]:
update,
MicrographResponse,
)
registered_request = CtfEstimationRegisteredRequest(
quality=True, metric_name="ctfmaxresolution"
) # True is a placeholder until we figure out the best way to calculate this
smartem_client._request(
"post",
f"micrographs/{movie.smartem_uuid}/ctf_estimation/registered",
registered_request,
ProcessingFeedbackPublishResponse,
)
except Exception:
logger.warning(
"Failed to emit CTF estimation complete event to smartem",
Expand Down
9 changes: 8 additions & 1 deletion src/murfey/workflows/spa/flush_spa_preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@
GridSquareMetadata as SmartEMGridSquareMetadata,
)

from murfey.util.config import get_security_config

keycloak_client = KeycloakClient(
load_keycloak_config(Path(os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION") or ""))
load_keycloak_config(
Path(
os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION")
or get_security_config().smartem_keycloak_config
)
)
)
SMARTEM_ACTIVE = True
except ImportError:
Expand Down
28 changes: 25 additions & 3 deletions src/murfey/workflows/spa/motion_correction.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,25 @@
try:
from smartem_backend.api_client import SmartEMAPIClient
from smartem_backend.keycloak_client import KeycloakClient, load_keycloak_config
from smartem_backend.model.http_request import MicrographUpdateRequest
from smartem_backend.model.http_response import MicrographResponse
from smartem_backend.model.http_request import (
MicrographUpdateRequest,
MotionCorrectionRegisteredRequest,
)
from smartem_backend.model.http_response import (
MicrographResponse,
ProcessingFeedbackPublishResponse,
)
from smartem_common.entity_status import MicrographStatus

from murfey.util.config import get_security_config

keycloak_client = KeycloakClient(
load_keycloak_config(Path(os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION") or ""))
load_keycloak_config(
Path(
os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION")
or get_security_config().smartem_keycloak_config
)
)
)
SMARTEM_ACTIVE = True
except ImportError:
Expand Down Expand Up @@ -57,6 +70,15 @@ def motion_corrected(message: dict, murfey_db: Session) -> dict[str, bool]:
update,
MicrographResponse,
)
registered_request = MotionCorrectionRegisteredRequest(
quality=True, metric_name="motioncorrection"
) # True is a placeholder until we figure out the best way to calculate this
smartem_client._request(
"post",
f"micrographs/{movie.smartem_uuid}/motion_correction/registered",
registered_request,
ProcessingFeedbackPublishResponse,
)
except Exception:
logger.warning(
"Failed to emit motion correction complete event to smartem",
Expand Down
9 changes: 8 additions & 1 deletion src/murfey/workflows/spa/picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@
from smartem_backend.model.http_response import MicrographResponse
from smartem_common.entity_status import MicrographStatus

from murfey.util.config import get_security_config

keycloak_client = KeycloakClient(
load_keycloak_config(Path(os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION") or ""))
load_keycloak_config(
Path(
os.getenv("SMARTEM_KEYCLOAK_CONFIGURATION")
or get_security_config().smartem_keycloak_config
)
)
)
SMARTEM_ACTIVE = True
except ImportError:
Expand Down