Skip to content

Commit 1dc1ea8

Browse files
Various bugfixes for processing job requests and tomo processing (#437)
--------- Co-authored-by: Dan Hatton <[email protected]>
1 parent 433a4d5 commit 1dc1ea8

File tree

11 files changed

+211
-74
lines changed

11 files changed

+211
-74
lines changed

src/murfey/client/contexts/spa.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ def _position_analysis(
570570
grid_square = _grid_square_from_file(transferred_file)
571571
grid_square_metadata_file = _grid_square_metadata_file(
572572
transferred_file,
573-
machine_config["data_directories"],
573+
[Path(p) for p in machine_config["data_directories"]],
574574
environment.visit,
575575
grid_square,
576576
)
@@ -921,6 +921,7 @@ def _register_processing_job(
921921
)
922922
msg: Dict[str, Any] = {
923923
"tag": tag,
924+
"source": tag,
924925
"recipe": "ispyb-relion",
925926
"parameters": {
926927
"acquisition_software": parameters["acquisition_software"],

src/murfey/client/contexts/spa_metadata.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import requests
66
import xmltodict
7-
from PIL import Image
87

98
from murfey.client.context import Context
109
from murfey.client.contexts.spa import _get_grid_square_atlas_positions, _get_source
@@ -85,17 +84,9 @@ def post_transfer(
8584
atlas_original_pixel_size = atlas_xml_data["MicroscopeImage"][
8685
"SpatialScale"
8786
]["pixelSize"]["x"]["numericValue"]
88-
readout_width = float(
89-
atlas_xml_data["MicroscopeImage"]["SpatialScale"]["pixelSize"]["x"][
90-
"numericValue"
91-
]
92-
)
9387

9488
# need to calculate the pixel size of the downscaled image
95-
atlas_im = Image.open(atlas_xml_path.with_suffix(".jpg"))
96-
atlas_pixel_size = atlas_original_pixel_size * (
97-
readout_width / atlas_im.width
98-
)
89+
atlas_pixel_size = atlas_original_pixel_size * 7.8
9990

10091
source = _get_source(
10192
visitless_path.parent / "Images-Disc1" / visitless_path.name,

src/murfey/client/contexts/tomo.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ def _add_tilt(
375375
proc_url,
376376
{
377377
"tag": tilt_series,
378+
"source": str(self._basepath),
378379
"recipe": "em-tomo-preprocess",
379380
"experiment_type": "tomography",
380381
},
@@ -385,6 +386,7 @@ def _add_tilt(
385386
proc_url,
386387
{
387388
"tag": tilt_series,
389+
"source": str(self._basepath),
388390
"recipe": "em-tomo-align",
389391
"experiment_type": "tomography",
390392
},
@@ -396,6 +398,7 @@ def _add_tilt(
396398
proc_url,
397399
json={
398400
"tag": tilt_series,
401+
"source": str(self._basepath),
399402
"recipe": "em-tomo-preprocess",
400403
"experiment_type": "tomography",
401404
},
@@ -404,6 +407,7 @@ def _add_tilt(
404407
proc_url,
405408
json={
406409
"tag": tilt_series,
410+
"source": str(self._basepath),
407411
"recipe": "em-tomo-align",
408412
"experiment_type": "tomography",
409413
},

src/murfey/client/multigrid_control.py

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -366,16 +366,9 @@ def _start_dc(self, json, from_form: bool = False):
366366
f"{self._environment.url.geturl()}/clients/{self._environment.client_id}/tomography_processing_parameters",
367367
json=json,
368368
)
369+
369370
source = Path(json["source"])
370-
self._environment.listeners["data_collection_group_ids"] = {
371-
context._flush_data_collections
372-
}
373-
self._environment.listeners["data_collection_ids"] = {
374-
context._flush_processing_job
375-
}
376-
self._environment.listeners["autoproc_program_ids"] = {
377-
context._flush_preprocess
378-
}
371+
379372
self._environment.id_tag_registry["data_collection_group"].append(
380373
str(source)
381374
)
@@ -386,12 +379,85 @@ def _start_dc(self, json, from_form: bool = False):
386379
"tag": str(source),
387380
}
388381
requests.post(url, json=dcg_data)
382+
383+
data = {
384+
"voltage": json["voltage"],
385+
"pixel_size_on_image": json["pixel_size_on_image"],
386+
"experiment_type": json["experiment_type"],
387+
"image_size_x": json["image_size_x"],
388+
"image_size_y": json["image_size_y"],
389+
"file_extension": json["file_extension"],
390+
"acquisition_software": json["acquisition_software"],
391+
"image_directory": str(self._environment.default_destinations[source]),
392+
"tag": json["tilt_series_tag"],
393+
"source": str(source),
394+
"magnification": json["magnification"],
395+
"total_exposed_dose": json.get("total_exposed_dose"),
396+
"c2aperture": json.get("c2aperture"),
397+
"exposure_time": json.get("exposure_time"),
398+
"slit_width": json.get("slit_width"),
399+
"phase_plate": json.get("phase_plate", False),
400+
}
401+
capture_post(
402+
f"{str(self._environment.url.geturl())}/visits/{str(self._environment.visit)}/{self._environment.murfey_session}/start_data_collection",
403+
json=data,
404+
)
405+
for recipe in ("em-tomo-preprocess", "em-tomo-align"):
406+
capture_post(
407+
f"{str(self._environment.url.geturl())}/visits/{str(self._environment.visit)}/{self._environment.murfey_session}/register_processing_job",
408+
json={
409+
"tag": json["tilt_series_tag"],
410+
"source": str(source),
411+
"recipe": recipe,
412+
},
413+
)
414+
log.info("Registering tomography processing parameters")
415+
if self._environment.data_collection_parameters.get("num_eer_frames"):
416+
eer_response = requests.post(
417+
f"{str(self._environment.url.geturl())}/visits/{self._environment.visit}/{self._environment.murfey_session}/eer_fractionation_file",
418+
json={
419+
"num_frames": self._environment.data_collection_parameters[
420+
"num_eer_frames"
421+
],
422+
"fractionation": self._environment.data_collection_parameters[
423+
"eer_fractionation"
424+
],
425+
"dose_per_frame": self._environment.data_collection_parameters[
426+
"dose_per_frame"
427+
],
428+
"fractionation_file_name": "eer_fractionation_tomo.txt",
429+
},
430+
)
431+
eer_fractionation_file = eer_response.json()["eer_fractionation_file"]
432+
json.update({"eer_fractionation_file": eer_fractionation_file})
433+
requests.post(
434+
f"{self._environment.url.geturl()}/sessions/{self._environment.murfey_session}/tomography_preprocessing_parameters",
435+
json=json,
436+
)
437+
context._flush_data_collections()
438+
context._flush_processing_jobs()
439+
capture_post(
440+
f"{self._environment.url.geturl()}/visits/{self._environment.visit}/{self._environment.murfey_session}/flush_tomography_processing",
441+
json={"rsync_source": str(source)},
442+
)
443+
log.info("tomography processing flushed")
444+
389445
elif isinstance(context, SPAContext) or isinstance(context, SPAModularContext):
390446
url = f"{str(self._environment.url.geturl())}/visits/{str(self._environment.visit)}/{self.session_id}/register_data_collection_group"
391447
dcg_data = {
392448
"experiment_type": "single particle",
393449
"experiment_type_id": 37,
394450
"tag": str(source),
451+
"atlas": (
452+
str(self._environment.samples[source].atlas)
453+
if self._environment.samples.get(source)
454+
else ""
455+
),
456+
"sample": (
457+
self._environment.samples[source].sample
458+
if self._environment.samples.get(source)
459+
else None
460+
),
395461
}
396462
capture_post(url, json=dcg_data)
397463
if from_form:
@@ -428,7 +494,11 @@ def _start_dc(self, json, from_form: bool = False):
428494
):
429495
capture_post(
430496
f"{str(self._environment.url.geturl())}/visits/{str(self._environment.visit)}/{self.session_id}/register_processing_job",
431-
json={"tag": str(source), "recipe": recipe},
497+
json={
498+
"tag": str(source),
499+
"source": str(source),
500+
"recipe": recipe,
501+
},
432502
)
433503
log.info(f"Posting SPA processing parameters: {json}")
434504
response = capture_post(

src/murfey/client/tui/app.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,11 @@ def _start_dc(self, json, from_form: bool = False):
516516
for recipe in ("em-tomo-preprocess", "em-tomo-align"):
517517
capture_post(
518518
f"{str(self._url.geturl())}/visits/{str(self._visit)}/{self._environment.murfey_session}/register_processing_job",
519-
json={"tag": json["tilt_series_tag"], "recipe": recipe},
519+
json={
520+
"tag": json["tilt_series_tag"],
521+
"source": str(source),
522+
"recipe": recipe,
523+
},
520524
)
521525
log.info("Registering tomography processing parameters")
522526
if self.app._environment.data_collection_parameters.get("num_eer_frames"):
@@ -600,7 +604,11 @@ def _start_dc(self, json, from_form: bool = False):
600604
):
601605
capture_post(
602606
f"{str(self._url.geturl())}/visits/{str(self._visit)}/{self._environment.murfey_session}/register_processing_job",
603-
json={"tag": str(source), "recipe": recipe},
607+
json={
608+
"tag": str(source),
609+
"source": str(source),
610+
"recipe": recipe,
611+
},
604612
)
605613
log.info(f"Posting SPA processing parameters: {json}")
606614
response = capture_post(

src/murfey/client/tui/screens.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,11 @@ def on_button_pressed(self, event: Button.Pressed):
717717
if self._switch_status:
718718
self.app.install_screen(
719719
DirectorySelection(
720-
[p for p in machine_data.get("data_directories", []) if p.exists()]
720+
[
721+
p
722+
for p in machine_data.get("data_directories", [])
723+
if Path(p).exists()
724+
]
721725
),
722726
"directory-select",
723727
)

src/murfey/server/__init__.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2471,19 +2471,16 @@ def _save_bfactor(message: dict, _db=murfey_db, demo: bool = False):
24712471
_transport_object.send(
24722472
"ispyb_connector",
24732473
{
2474-
"parameters": {
2475-
"ispyb_command": "buffer",
2476-
"buffer_lookup": {
2477-
"particle_classification_id": refined_class_uuid,
2478-
},
2479-
"buffer_command": {
2480-
"ispyb_command": "insert_particle_classification"
2481-
},
2482-
"program_id": message["program_id"],
2483-
"bfactor_fit_intercept": str(bfactor_fitting[1]),
2484-
"bfactor_fit_linear": str(bfactor_fitting[0]),
2474+
"ispyb_command": "buffer",
2475+
"buffer_lookup": {
2476+
"particle_classification_id": refined_class_uuid,
2477+
},
2478+
"buffer_command": {
2479+
"ispyb_command": "insert_particle_classification"
24852480
},
2486-
"content": {"dummy": "dummy"},
2481+
"program_id": message["program_id"],
2482+
"bfactor_fit_intercept": str(bfactor_fitting[1]),
2483+
"bfactor_fit_linear": str(bfactor_fitting[0]),
24872484
},
24882485
new_connection=True,
24892486
)
@@ -2639,7 +2636,9 @@ def feedback_callback(header: dict, message: dict) -> None:
26392636
cassetteSlot=message.get("sample"),
26402637
)
26412638
if _transport_object:
2642-
atlas_id = _transport_object.do_insert_atlas(atlas_record)
2639+
atlas_id = _transport_object.do_insert_atlas(atlas_record)[
2640+
"return_value"
2641+
]
26432642
murfey_dcg = db.DataCollectionGroup(
26442643
id=dcgid,
26452644
atlas_id=atlas_id,
@@ -2756,7 +2755,6 @@ def feedback_callback(header: dict, message: dict) -> None:
27562755
elif message["register"] == "processing_job":
27572756
murfey_session_id = message["session_id"]
27582757
logger.info("registering processing job")
2759-
assert isinstance(global_state["data_collection_ids"], dict)
27602758
dc = murfey_db.exec(
27612759
select(db.DataCollection, db.DataCollectionGroup)
27622760
.where(db.DataCollection.dcg_id == db.DataCollectionGroup.id)

src/murfey/server/api/__init__.py

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import sqlalchemy
1212
from fastapi import APIRouter, Depends, Request
1313
from fastapi.responses import FileResponse, HTMLResponse
14+
from ispyb.sqlalchemy import Atlas
1415
from ispyb.sqlalchemy import AutoProcProgram as ISPyBAutoProcProgram
1516
from ispyb.sqlalchemy import (
1617
BLSample,
@@ -611,7 +612,7 @@ def register_foil_hole(
611612
except Exception:
612613
if _transport_object:
613614
fh_ispyb_response = _transport_object.do_insert_foil_hole(
614-
gsid.id, gs.thumbnail_size_x / gs.readout_area_x, foil_hole_params
615+
gs.id, gs.thumbnail_size_x / gs.readout_area_x, foil_hole_params
615616
)
616617
else:
617618
fh_ispyb_response = {"success": False, "return_value": None}
@@ -1339,7 +1340,7 @@ def suggest_path(
13391340
check_path = machine_config.rsync_basepath / base_path
13401341

13411342
# Check previous year to account for the year rolling over during data collection
1342-
if not check_path.exists():
1343+
if not check_path.parent.exists():
13431344
base_path_parts = base_path.split("/")
13441345
for part in base_path_parts:
13451346
# Find the path part corresponding to the year
@@ -1351,10 +1352,10 @@ def suggest_path(
13511352
check_path = machine_config.rsync_basepath / base_path
13521353

13531354
# If it's not in the previous year either, it's a genuine error
1354-
if not check_path.exists():
1355+
if not check_path.parent.exists():
13551356
log_message = (
13561357
"Unable to find current visit folder under "
1357-
f"{str(check_path_prev)!r} or {str(check_path)!r}"
1358+
f"{str(check_path_prev.parent)!r} or {str(check_path.parent)!r}"
13581359
)
13591360
log.error(log_message)
13601361
raise FileNotFoundError(log_message)
@@ -1370,9 +1371,13 @@ def suggest_path(
13701371
return {"suggested_path": check_path.relative_to(machine_config.rsync_basepath)}
13711372

13721373

1373-
@router.post("/{session_id}/make_rsyncer_destination")
1374-
def make_rsyncer_destination(session_id: int, destination: Path, db=murfey_db):
1375-
secure_path_parts = [secure_filename(p) for p in destination.parts]
1374+
class Dest(BaseModel):
1375+
destination: Path
1376+
1377+
1378+
@router.post("/sessions/{session_id}/make_rsyncer_destination")
1379+
def make_rsyncer_destination(session_id: int, destination: Dest, db=murfey_db):
1380+
secure_path_parts = [secure_filename(p) for p in destination.destintion.parts]
13761381
destination_path = "/".join(secure_path_parts)
13771382
instrument_name = (
13781383
db.exec(select(Session).where(Session.id == session_id)).one().instrument_name
@@ -1427,19 +1432,31 @@ def register_dc_group(
14271432
dcg_murfey[0].atlas = dcg_params.atlas
14281433
dcg_murfey[0].sample = dcg_params.sample
14291434
dcg_murfey[0].atlas_pixel_size = dcg_params.atlas_pixel_size
1435+
1436+
if _transport_object:
1437+
if dcg_murfey[0].atlas_id is not None:
1438+
_transport_object.send(
1439+
_transport_object.feedback_queue,
1440+
{
1441+
"register": "atlas_update",
1442+
"atlas_id": dcg_murfey[0].atlas_id,
1443+
"atlas": dcg_params.atlas,
1444+
"sample": dcg_params.sample,
1445+
"atlas_pixel_size": dcg_params.atlas_pixel_size,
1446+
},
1447+
)
1448+
else:
1449+
atlas_id_response = _transport_object.do_insert_atlas(
1450+
Atlas(
1451+
dataCollectionGroupId=dcg_murfey[0].id,
1452+
atlasImage=dcg_params.atlas,
1453+
pixelSize=dcg_params.atlas_pixel_size,
1454+
cassetteSlot=dcg_params.sample,
1455+
)
1456+
)
1457+
dcg_murfey[0].atlas_id = atlas_id_response["return_value"]
14301458
db.add(dcg_murfey[0])
14311459
db.commit()
1432-
if _transport_object:
1433-
_transport_object.send(
1434-
_transport_object.feedback_queue,
1435-
{
1436-
"register": "atlas_update",
1437-
"atlas_id": dcg_murfey.atlas_id,
1438-
"atlas": dcg_params.atlas,
1439-
"sample": dcg_params.sample,
1440-
"atlas_pixel_size": dcg_params.atlas_pixel_size,
1441-
},
1442-
)
14431460
else:
14441461
dcg_parameters = {
14451462
"start_time": str(datetime.datetime.now()),
@@ -1528,6 +1545,7 @@ def register_proc(
15281545
"session_id": session_id,
15291546
"experiment_type": proc_params.experiment_type,
15301547
"recipe": proc_params.recipe,
1548+
"source": proc_params.source,
15311549
"tag": proc_params.tag,
15321550
"job_parameters": {
15331551
k: v for k, v in proc_params.parameters.items() if v not in (None, "None")

0 commit comments

Comments
 (0)