Skip to content

Commit 4609edd

Browse files
committed
Merged recent changes from 'main' branch
2 parents f8ffd2c + 0187914 commit 4609edd

17 files changed

Lines changed: 325 additions & 181 deletions

src/murfey/client/contexts/atlas.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from murfey.client.context import Context, _atlas_destination, _get_source
88
from murfey.client.instance_environment import MurfeyInstanceEnvironment
99
from murfey.util.client import capture_post
10+
from murfey.util.spa_metadata import get_grid_square_atlas_positions
1011

1112
logger = logging.getLogger("murfey.client.contexts.atlas")
1213

@@ -158,3 +159,52 @@ def post_transfer_epu(
158159
logger.info(
159160
f"Registered data collection group for atlas {str(transferred_atlas_jpg)!r}"
160161
)
162+
163+
elif environment and transferred_file.name == "Atlas.dm":
164+
# Register all grid squares on this atlas
165+
gs_pix_positions = get_grid_square_atlas_positions(transferred_file)
166+
for gs, pos_data in gs_pix_positions.items():
167+
if pos_data:
168+
capture_post(
169+
base_url=str(environment.url.geturl()),
170+
router_name="session_control.spa_router",
171+
function_name="register_grid_square",
172+
token=self._token,
173+
instrument_name=environment.instrument_name,
174+
session_id=environment.murfey_session,
175+
gsid=int(gs),
176+
data={
177+
"tag": str(transferred_file.parent),
178+
"x_location": pos_data[0],
179+
"y_location": pos_data[1],
180+
"x_stage_position": pos_data[2],
181+
"y_stage_position": pos_data[3],
182+
"width": pos_data[4],
183+
"height": pos_data[5],
184+
"angle": pos_data[6],
185+
},
186+
)
187+
if gs_pix_positions:
188+
for p in transferred_file.parts:
189+
if p.startswith("Sample"):
190+
sample = int(p.replace("Sample", ""))
191+
break
192+
else:
193+
logger.warning(
194+
f"Sample could not be identified for {transferred_file}"
195+
)
196+
return
197+
capture_post(
198+
base_url=str(environment.url.geturl()),
199+
router_name="session_control.spa_router",
200+
function_name="register_atlas",
201+
token=self._token,
202+
instrument_name=environment.instrument_name,
203+
session_id=environment.murfey_session,
204+
data={
205+
"name": f"{environment.visit}-sample-{sample}",
206+
"acquisition_uuid": environment.acquisition_uuid,
207+
"register_grid": True,
208+
"tag": str(transferred_file.parent),
209+
},
210+
)

src/murfey/client/contexts/spa_metadata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def post_transfer(
152152
"angle": pos_data[6],
153153
},
154154
)
155-
if pos_data:
155+
if gs_pix_positions:
156156
capture_post(
157157
base_url=str(environment.url.geturl()),
158158
router_name="session_control.spa_router",

src/murfey/server/api/session_control.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ def get_foil_hole(
359359

360360
class AtlasRegistration(BaseModel):
361361
name: str
362-
acquisition_uuid: str
362+
acquisition_uuid: str | None
363363
storage_folder: str = ""
364364
register_grid: bool = False
365365
tag: str = ""
@@ -371,7 +371,7 @@ def register_atlas(
371371
atlas_registration_data: AtlasRegistration,
372372
db=murfey_db,
373373
):
374-
if SMARTEM_ACTIVE:
374+
if SMARTEM_ACTIVE and atlas_registration_data.acquisition_uuid is not None:
375375
session = db.exec(select(Session).where(Session.id == session_id)).one()
376376
machine_config = get_machine_config(session.instrument_name)[
377377
session.instrument_name
@@ -382,7 +382,7 @@ def register_atlas(
382382
)
383383
grid_uuid = None
384384
if atlas_registration_data.tag:
385-
dcg = murfey_db.exec(
385+
dcg = db.exec(
386386
select(DataCollectionGroup)
387387
.where(DataCollectionGroup.session_id == session_id)
388388
.where(DataCollectionGroup.tag == atlas_registration_data.tag)
@@ -410,7 +410,9 @@ def register_atlas(
410410
if atlas_registration_data.register_grid:
411411
smartem_client.grid_registered(grid_uuid)
412412
else:
413-
logger.info("smartem deactivated so did not register atlas")
413+
logger.info(
414+
f"smartem deactivated so did not register atlas for {sanitise(str(atlas_registration_data.acquisition_uuid))}"
415+
)
414416

415417

416418
class SquareRegistration(BaseModel):

src/murfey/server/api/workflow.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ def register_dc_group(
232232
)
233233
).all():
234234
# Case where we switch from atlas to processing
235+
original_tag = dcg_murfey[0].tag
235236
dcg_murfey[0].tag = dcg_params.tag or dcg_murfey[0].tag
236237
if _transport_object:
237238
_transport_object.send(
@@ -243,6 +244,13 @@ def register_dc_group(
243244
},
244245
)
245246
db.add(dcg_murfey[0])
247+
for grid_square in db.exec(
248+
select(GridSquare)
249+
.where(GridSquare.tag == original_tag)
250+
.where(GridSquare.session_id == session_id)
251+
).all():
252+
grid_square.tag = dcg_params.tag or original_tag
253+
db.add(grid_square)
246254
db.commit()
247255
else:
248256
dcg_parameters = {

src/murfey/server/feedback.py

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from sqlalchemy import func
2626
from sqlalchemy.exc import (
2727
InvalidRequestError,
28+
NoResultFound,
2829
OperationalError,
2930
PendingRollbackError,
3031
SQLAlchemyError,
@@ -353,7 +354,6 @@ def _release_2d_hold(message: dict, _db):
353354
"nr_classes": default_spa_parameters.nr_classes_2d,
354355
"do_icebreaker_jobs": default_spa_parameters.do_icebreaker_jobs,
355356
"class2d_fraction_of_classes_to_remove": default_spa_parameters.fraction_of_classes_to_remove_2d,
356-
"picker_id": feedback_params.picker_ispyb_id,
357357
"class_uuids": _2d_class_murfey_ids(
358358
first_class2d.particles_file, message["program_id"], _db
359359
),
@@ -431,7 +431,6 @@ def _release_3d_hold(message: dict, _db):
431431
"mask_diameter": relion_params.mask_diameter or 0,
432432
"do_initial_model": False if feedback_params.initial_model else True,
433433
"initial_model_file": feedback_params.initial_model,
434-
"picker_id": feedback_params.picker_ispyb_id,
435434
"class_uuids": _3d_class_murfey_ids(
436435
class3d_params.particles_file, _app_id(pj_id, _db), _db
437436
),
@@ -517,7 +516,6 @@ def _release_refine_hold(message: dict, _db):
517516
"symmetry": relion_params.symmetry,
518517
"node_creator_queue": machine_config.node_creator_queue,
519518
"nr_iter": default_spa_parameters.nr_iter_3d,
520-
"picker_id": feedback_params.picker_ispyb_id,
521519
"refined_class_uuid": _refine_murfey_id(
522520
refine_dir=refine_params.refine_dir,
523521
tag=refine_params.tag,
@@ -589,13 +587,6 @@ def _register_incomplete_2d_batch(message: dict, _db):
589587
feedback_params.hold_class2d = True
590588
relion_options = dict(relion_params)
591589
other_options = dict(feedback_params)
592-
if other_options["picker_ispyb_id"] is None:
593-
logger.info("No ISPyB particle picker ID yet")
594-
feedback_params.hold_class2d = False
595-
_db.add(feedback_params)
596-
_db.commit()
597-
_db.expunge(feedback_params)
598-
return
599590
_db.add(feedback_params)
600591
_db.commit()
601592
_db.expunge(feedback_params)
@@ -629,7 +620,6 @@ def _register_incomplete_2d_batch(message: dict, _db):
629620
"batch_is_complete": False,
630621
"particle_diameter": relion_options["particle_diameter"],
631622
"combine_star_job_number": -1,
632-
"picker_id": other_options["picker_ispyb_id"],
633623
"nr_iter": default_spa_parameters.nr_iter_2d,
634624
"batch_size": default_spa_parameters.batch_size_2d,
635625
"nr_classes": default_spa_parameters.nr_classes_2d,
@@ -693,7 +683,7 @@ def _register_complete_2d_batch(message: dict, _db):
693683
).one()
694684
_db.expunge(relion_params)
695685
_db.expunge(feedback_params)
696-
if feedback_params.hold_class2d or feedback_params.picker_ispyb_id is None:
686+
if feedback_params.hold_class2d:
697687
feedback_params.rerun_class2d = True
698688
_db.add(feedback_params)
699689
_db.commit()
@@ -791,7 +781,6 @@ def _register_complete_2d_batch(message: dict, _db):
791781
"mask_diameter": relion_params.mask_diameter or 0,
792782
"combine_star_job_number": feedback_params.star_combination_job,
793783
"autoselect_min_score": 0,
794-
"picker_id": feedback_params.picker_ispyb_id,
795784
"class_uuids": class_uuids,
796785
"class2d_grp_uuid": class2d_grp_uuid,
797786
"nr_iter": default_spa_parameters.nr_iter_2d,
@@ -866,7 +855,6 @@ def _register_complete_2d_batch(message: dict, _db):
866855
"mask_diameter": relion_params.mask_diameter or 0,
867856
"combine_star_job_number": feedback_params.star_combination_job,
868857
"autoselect_min_score": feedback_params.class_selection_score or 0,
869-
"picker_id": feedback_params.picker_ispyb_id,
870858
"class_uuids": class_uuids,
871859
"class2d_grp_uuid": class2d_grp_uuid,
872860
"nr_iter": default_spa_parameters.nr_iter_2d,
@@ -957,7 +945,6 @@ def _flush_class2d(
957945
"mask_diameter": relion_params.mask_diameter or 0,
958946
"combine_star_job_number": feedback_params.star_combination_job,
959947
"autoselect_min_score": feedback_params.class_selection_score or 0,
960-
"picker_id": feedback_params.picker_ispyb_id,
961948
"class_uuids": _2d_class_murfey_ids(
962949
saved_message.particles_file, _app_id(pj_id, _db), _db
963950
),
@@ -1007,16 +994,6 @@ def _register_class_selection(message: dict, _db):
1007994
).one()
1008995
_db.expunge(feedback_params)
1009996

1010-
if feedback_params.picker_ispyb_id is None:
1011-
selection_stash = db.SelectionStash(
1012-
pj_id=pj_id,
1013-
class_selection_score=message["class_selection_score"] or 0,
1014-
)
1015-
_db.add(selection_stash)
1016-
_db.commit()
1017-
_db.close()
1018-
return
1019-
1020997
feedback_params.class_selection_score = message.get("class_selection_score") or 0
1021998
feedback_params.hold_class2d = False
1022999
_flush_class2d(
@@ -1284,7 +1261,6 @@ def _register_3d_batch(message: dict, _db):
12841261
"particle_diameter": relion_options["particle_diameter"],
12851262
"mask_diameter": relion_options["mask_diameter"] or 0,
12861263
"do_initial_model": True,
1287-
"picker_id": other_options["picker_ispyb_id"],
12881264
"class_uuids": {i + 1: m for i, m in enumerate(class_uuids)},
12891265
"class3d_grp_uuid": class3d_grp_uuid,
12901266
"nr_iter": default_spa_parameters.nr_iter_3d,
@@ -1325,7 +1301,6 @@ def _register_3d_batch(message: dict, _db):
13251301
"mask_diameter": relion_options["mask_diameter"] or 0,
13261302
"do_initial_model": False,
13271303
"initial_model_file": other_options["initial_model"],
1328-
"picker_id": other_options["picker_ispyb_id"],
13291304
"class_uuids": _3d_class_murfey_ids(
13301305
class3d_params.particles_file, _app_id(pj_id, _db), _db
13311306
),
@@ -1534,7 +1509,6 @@ def _register_refinement(message: dict, _db):
15341509
db.ClassificationFeedbackParameters.pj_id == pj_id_params
15351510
)
15361511
).one()
1537-
other_options = dict(feedback_params)
15381512

15391513
if feedback_params.hold_refine:
15401514
# If waiting then save the message
@@ -1626,7 +1600,6 @@ def _register_refinement(message: dict, _db):
16261600
"symmetry": relion_options["symmetry"],
16271601
"node_creator_queue": machine_config.node_creator_queue,
16281602
"nr_iter": default_spa_parameters.nr_iter_3d,
1629-
"picker_id": other_options["picker_ispyb_id"],
16301603
"refined_class_uuid": _refine_murfey_id(
16311604
refine_dir=refine_params.refine_dir,
16321605
tag=refine_params.tag,
@@ -1761,7 +1734,6 @@ def _register_bfactors(message: dict, _db):
17611734
"particle_diameter": relion_options["particle_diameter"],
17621735
"mask_diameter": relion_options["mask_diameter"] or 0,
17631736
"node_creator_queue": machine_config.node_creator_queue,
1764-
"picker_id": feedback_params.picker_ispyb_id,
17651737
"refined_grp_uuid": bfactor_params.refined_grp_uuid,
17661738
"refined_class_uuid": bfactor_params.refined_class_uuid,
17671739
"session_id": message["session_id"],
@@ -2189,6 +2161,12 @@ def feedback_callback(header: dict, message: dict, _db=murfey_db) -> None:
21892161
time.sleep(1)
21902162
if murfey.server._transport_object:
21912163
murfey.server._transport_object.transport.nack(header, requeue=True)
2164+
except NoResultFound:
2165+
# Missing rows might be due to a race condition and should be requeued
2166+
logger.warning("No matching database row was found", exc_info=True)
2167+
time.sleep(1)
2168+
if murfey.server._transport_object:
2169+
murfey.server._transport_object.transport.nack(header, requeue=True)
21922170
except Exception:
21932171
logger.warning(
21942172
"Exception encountered in server RabbitMQ callback", exc_info=True

src/murfey/util/db.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,6 @@ class ProcessingJob(SQLModel, table=True): # type: ignore
339339
auto_proc_programs: List["AutoProcProgram"] = Relationship(
340340
back_populates="processing_job", sa_relationship_kwargs={"cascade": "delete"}
341341
)
342-
selection_stash: List["SelectionStash"] = Relationship(
343-
back_populates="processing_job", sa_relationship_kwargs={"cascade": "delete"}
344-
)
345342
particle_sizes: List["ParticleSizes"] = Relationship(
346343
back_populates="processing_job", sa_relationship_kwargs={"cascade": "delete"}
347344
)
@@ -393,15 +390,6 @@ class PreprocessStash(SQLModel, table=True): # type: ignore
393390
foil_hole: Optional["FoilHole"] = Relationship(back_populates="preprocess_stashes")
394391

395392

396-
class SelectionStash(SQLModel, table=True): # type: ignore
397-
id: Optional[int] = Field(default=None, primary_key=True)
398-
class_selection_score: float
399-
pj_id: int = Field(foreign_key="processingjob.processingJobId")
400-
processing_job: Optional[ProcessingJob] = Relationship(
401-
back_populates="selection_stash"
402-
)
403-
404-
405393
class TomographyProcessingParameters(SQLModel, table=True): # type: ignore
406394
dcg_id: int = Field(
407395
primary_key=True, foreign_key="datacollectiongroup.dataCollectionGroupId"
@@ -717,7 +705,6 @@ class ClassificationFeedbackParameters(SQLModel, table=True): # type: ignore
717705
initial_model: str
718706
next_job: int
719707
picker_murfey_id: Optional[int] = Field(default=None, foreign_key="murfeyledger.id")
720-
picker_ispyb_id: Optional[int] = None
721708
processing_job: Optional[ProcessingJob] = Relationship(
722709
back_populates="classification_feedback_parameters"
723710
)

src/murfey/util/processing_params.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from datetime import datetime
22
from functools import lru_cache
33
from pathlib import Path
4-
from typing import Literal, Optional
54

65
from pydantic import BaseModel
76
from werkzeug.utils import secure_filename
@@ -60,12 +59,6 @@ class CLEMProcessingParameters(BaseModel):
6059
# Atlas vs GridSquare registration threshold
6160
atlas_threshold: float = 0.0015 # in m
6261

63-
# Image alignment and merging-specific parameters
64-
crop_to_n_frames: Optional[int] = 50
65-
align_self: Literal["enabled", ""] = "enabled"
66-
flatten: Literal["mean", "min", "max", ""] = "mean"
67-
align_across: Literal["enabled", ""] = "enabled"
68-
6962

7063
default_clem_processing_parameters = CLEMProcessingParameters()
7164

src/murfey/workflows/clem/align_and_merge.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from __future__ import annotations
77

88
from pathlib import Path
9-
from typing import Literal, Optional
9+
from typing import Optional
1010

1111
from murfey.util.config import get_machine_config
1212

@@ -24,11 +24,6 @@ def run(
2424
series_name: str,
2525
images: list[Path],
2626
metadata: Path,
27-
# Optional processing parameters
28-
crop_to_n_frames: Optional[int] = None,
29-
align_self: Literal["enabled", ""] = "",
30-
flatten: Literal["mean", "min", "max", ""] = "mean",
31-
align_across: Literal["enabled", ""] = "",
3227
# Optional session parameters
3328
messenger: Optional[TransportManager] = None,
3429
):
@@ -65,10 +60,6 @@ def run(
6560
"series_name": series_name,
6661
"images": [str(file) for file in images],
6762
"metadata": str(metadata),
68-
"crop_to_n_frames": crop_to_n_frames,
69-
"align_self": align_self,
70-
"flatten": flatten,
71-
"align_across": align_across,
7263
# Other recipe parameters
7364
"session_dir": str(session_dir),
7465
"session_id": session_id,

0 commit comments

Comments
 (0)