Skip to content

Commit a7385ed

Browse files
B24 display fixes (#262)
Fixes a few display issues with the images for b24 tomograms: Tomo align should display YZ not XZ The text on the alignment image assumed the image was bigger than it is for b24, so a scaling is now applied Uses olefile directly where possible rather than txrm2tiff Two parameters in the recipe should not be hard-coded This is not the full set of fixes needed, but does make the displays work. Also needed will be to make the alignment image tilt on the opposite axis, and display the motion in different units TBC.
1 parent e700c91 commit a7385ed

4 files changed

Lines changed: 66 additions & 66 deletions

File tree

recipes/ispyb/sxt-aretomo.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
},
2424
"parameters": {
2525
"dark_tol": 0,
26-
"manual_tilt_offset": 0,
26+
"manual_tilt_offset": "{manual_tilt_offset}",
2727
"out_bin": 1,
28-
"pixel_size": 100,
28+
"pixel_size": "{pixel_size}",
2929
"relion_options": {},
3030
"stack_file": "{stack_file}",
3131
"tilt_axis": 0,

src/cryoemservices/services/images_plugins.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -884,17 +884,38 @@ def tilt_series_alignment(plugin_params: Callable):
884884
)
885885

886886
# Text to record outliers and colour key
887+
text_scaling = flat_size[0] / 4096
887888
if outliers:
888889
dim.text(
889-
(100, cen[1] * 2 - 200),
890+
(100 * text_scaling, cen[1] * 2 - 200 * text_scaling),
890891
"Outliers (deg): " + " ".join(outliers),
891892
fill="#f52407",
892-
font_size=150,
893+
font_size=150 * text_scaling,
893894
)
894-
dim.text((100, 10), "Shift over 100 nm", fill="#f52407", font_size=150)
895-
dim.text((100, 160), "Shift 10 to 100 nm", fill="#f5a927", font_size=150)
896-
dim.text((100, 320), "Shift 1 to 10 nm", fill="#f5e90a", font_size=150)
897-
dim.text((100, 460), "Shift under 1 nm", fill="#0af549", font_size=150)
895+
dim.text(
896+
(100 * text_scaling, 10),
897+
"Shift over 100 nm",
898+
fill="#f52407",
899+
font_size=150 * text_scaling,
900+
)
901+
dim.text(
902+
(100 * text_scaling, 10 + 150 * text_scaling),
903+
"Shift 10 to 100 nm",
904+
fill="#f5a927",
905+
font_size=150 * text_scaling,
906+
)
907+
dim.text(
908+
(100 * text_scaling, 10 + 300 * text_scaling),
909+
"Shift 1 to 10 nm",
910+
fill="#f5e90a",
911+
font_size=150 * text_scaling,
912+
)
913+
dim.text(
914+
(100 * text_scaling, 10 + 450 * text_scaling),
915+
"Shift under 1 nm",
916+
fill="#0af549",
917+
font_size=150 * text_scaling,
918+
)
898919
colour_im.thumbnail((1024, 1024))
899920
colour_im.save(outfile)
900921
timing = time.perf_counter() - start

src/cryoemservices/services/tomo_align.py

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,9 @@
1313
import numpy as np
1414
import plotly.express as px
1515
from gemmi import cif
16+
from olefile import OleFileIO
1617
from pydantic import BaseModel, Field, ValidationError, field_validator, model_validator
17-
from txrm2tiff.inspector import Inspector
1818
from txrm2tiff.main import convert_and_save
19-
from txrm2tiff.txrm import open_txrm
20-
from txrm2tiff.txrm_functions.general import read_stream
21-
from txrm2tiff.xradia_properties.enums import XrmDataTypes
2219
from workflows.recipe import wrap_subscribe
2320

2421
from cryoemservices.services.common_service import CommonService
@@ -601,6 +598,11 @@ def _tilt(file_list_for_tilts):
601598
)
602599

603600
# Forward tomogram (one per-tilt-series)
601+
side_projection = (
602+
"YZ"
603+
if tomo_params.tilt_axis is not None and -45 < tomo_params.tilt_axis < 45
604+
else "XZ"
605+
)
604606
ispyb_command_list = [
605607
{
606608
"ispyb_command": "insert_tomogram",
@@ -621,7 +623,7 @@ def _tilt(file_list_for_tilts):
621623
"tomogram_movie": stack_name + "_Vol_movie.png",
622624
"xy_shift_plot": plot_file,
623625
"proj_xy": stack_name + "_Vol_projXY.jpeg",
624-
"proj_xz": stack_name + "_Vol_projXZ.jpeg",
626+
"proj_xz": stack_name + f"_Vol_proj{side_projection}.jpeg",
625627
"alignment_quality": str(self.alignment_quality),
626628
}
627629
]
@@ -800,11 +802,6 @@ def _tilt(file_list_for_tilts):
800802
)
801803

802804
self.log.info("Sending to images service for XY and XZ projections")
803-
side_projection = (
804-
"YZ"
805-
if tomo_params.tilt_axis is not None and -45 < tomo_params.tilt_axis < 45
806-
else "XZ"
807-
)
808805
for projection_type in ["XY", side_projection]:
809806
images_call_params: dict[str, str | float] = {
810807
"image_command": "mrc_projection",
@@ -859,33 +856,28 @@ def _tilt(file_list_for_tilts):
859856

860857
def convert_txrm_to_stack(self, txrm_file: str, stack_file: str) -> float:
861858
# Read the tilt angles and pixel size from the txrm
862-
with open_txrm(
863-
txrm_file, load_images=False, load_reference=False, strict=False
864-
) as txrm:
865-
inspector = Inspector(txrm)
866-
angles = read_stream(
867-
inspector.txrm.ole,
868-
"ImageInfo/Angles",
869-
XrmDataTypes.XRM_FLOAT,
870-
strict=True,
871-
)
872-
pixel_size_microns = read_stream(
873-
inspector.txrm.ole,
874-
"ImageInfo/PixelSize",
875-
XrmDataTypes.XRM_FLOAT,
876-
strict=True,
877-
)
878-
self.tilt_angles = dict(enumerate(angles))
859+
pixel_size_angstroms = 100
860+
with OleFileIO(txrm_file) as txrm_ole:
861+
if txrm_ole.exists("ImageInfo/Angles"):
862+
angles = np.frombuffer(
863+
txrm_ole.openstream("ImageInfo/Angles").getvalue(), np.float32
864+
).tolist()
865+
self.tilt_angles = dict(enumerate(angles))
866+
867+
if txrm_ole.exists("ImageInfo/PixelSize"):
868+
pixel_size_microns = np.frombuffer(
869+
txrm_ole.openstream("ImageInfo/PixelSize").getvalue(),
870+
np.float32,
871+
).tolist()
872+
pixel_size_angstroms = round(pixel_size_microns[0] * 1e4, 2)
879873

880874
# Convert the txrm to a tiff stack, then convert to mrc for aretomo
881875
tifftomo = Path(stack_file).with_suffix(".tiff")
882876
convert_and_save(txrm_file, str(tifftomo), custom_reference=None)
883877
# Let this run, and check later if the output file exists
884878
subprocess.run(["tif2mrc", str(tifftomo), stack_file])
885879
tifftomo.unlink(missing_ok=True)
886-
if pixel_size_microns:
887-
return pixel_size_microns[0] * 1000
888-
return 100
880+
return pixel_size_angstroms
889881

890882
def assemble_aretomo3_command(
891883
self,

tests/services/test_tomo_align.py

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import mrcfile
1010
import numpy as np
1111
import pytest
12-
from txrm2tiff.xradia_properties.enums import XrmDataTypes
1312
from workflows.transport.offline_transport import OfflineTransport
1413

1514
from cryoemservices.services import tomo_align
@@ -2084,17 +2083,13 @@ def write_aretomo_outputs(command, capture_output):
20842083
@mock.patch("cryoemservices.services.tomo_align.subprocess.run")
20852084
@mock.patch("cryoemservices.services.tomo_align.mrcfile")
20862085
@mock.patch("cryoemservices.services.tomo_align.convert_and_save")
2087-
@mock.patch("cryoemservices.services.tomo_align.open_txrm")
2088-
@mock.patch("cryoemservices.services.tomo_align.Inspector")
2089-
@mock.patch("cryoemservices.services.tomo_align.read_stream")
2086+
@mock.patch("cryoemservices.services.tomo_align.OleFileIO")
20902087
@mock.patch("cryoemservices.services.tomo_align.resize_tomogram")
20912088
@mock.patch("cryoemservices.services.tomo_align.rotate_tomogram")
20922089
def test_tomo_align_service_txrm(
20932090
mock_rotate,
20942091
mock_resize,
2095-
mock_read_stream,
2096-
mock_inspector,
2097-
mock_open_txrm,
2092+
mock_ole_file,
20982093
mock_convert_and_save,
20992094
mock_mrcfile,
21002095
mock_subprocess,
@@ -2105,7 +2100,10 @@ def test_tomo_align_service_txrm(
21052100
Send a test message to TomoAlign (AreTomo3) for a txrm file
21062101
"""
21072102
mock_mrcfile.open().__enter__().header = MrcFileHeader(nx=4000, ny=3000, nz=600)
2108-
mock_read_stream.return_value = [0.1, 0.3, 0.5]
2103+
mock_ole_file().__enter__().exists.return_value = True
2104+
mock_ole_file().__enter__().openstream().getvalue.return_value = np.array(
2105+
[0.01, 0.3, 0.5], dtype=np.float32
2106+
).tobytes()
21092107

21102108
header = {
21112109
"message-id": mock.sentinel,
@@ -2199,26 +2197,15 @@ def write_aretomo_outputs(command, capture_output: bool = False):
21992197
]
22002198

22012199
# Check txrm file reading
2202-
mock_open_txrm.assert_called_once_with(
2203-
tomo_align_test_message["txrm_file"],
2204-
load_images=False,
2205-
load_reference=False,
2206-
strict=False,
2207-
)
2208-
mock_open_txrm().__enter__.assert_called_once()
2209-
mock_inspector.assert_called_once()
2210-
mock_read_stream.assert_any_call(
2211-
mock.ANY,
2200+
mock_ole_file.assert_any_call(tomo_align_test_message["txrm_file"])
2201+
assert mock_ole_file().__enter__().exists.call_count == 2
2202+
assert mock_ole_file().__enter__().openstream.call_count == 3 # 2 + 1 above
2203+
for field_name in [
22122204
"ImageInfo/Angles",
2213-
XrmDataTypes.XRM_FLOAT,
2214-
strict=True,
2215-
)
2216-
mock_read_stream.assert_any_call(
2217-
mock.ANY,
22182205
"ImageInfo/PixelSize",
2219-
XrmDataTypes.XRM_FLOAT,
2220-
strict=True,
2221-
)
2206+
]:
2207+
mock_ole_file().__enter__().exists.assert_any_call(field_name)
2208+
mock_ole_file().__enter__().openstream.assert_any_call(field_name)
22222209
mock_convert_and_save.assert_called_once_with(
22232210
tomo_align_test_message["txrm_file"],
22242211
f"{tmp_path}/Tomograms/stack.tiff",
@@ -2247,7 +2234,7 @@ def write_aretomo_outputs(command, capture_output: bool = False):
22472234
assert (tmp_path / "Tomograms/stack_TLT.txt").is_file()
22482235
with open(tmp_path / "Tomograms/stack_TLT.txt", "r") as angfile:
22492236
angles_data = angfile.read()
2250-
assert angles_data == "0.10 0\n0.30 1\n0.50 2\n"
2237+
assert angles_data == "0.01 0\n0.30 1\n0.50 2\n"
22512238

22522239
# Check the shift plot
22532240
with open(tmp_path / "Tomograms/stack_xy_shift_plot.json") as shift_plot:
@@ -2277,7 +2264,7 @@ def write_aretomo_outputs(command, capture_output: bool = False):
22772264
"tomogram_movie": "stack_Vol_movie.png",
22782265
"xy_shift_plot": "stack_xy_shift_plot.json",
22792266
"proj_xy": "stack_Vol_projXY.jpeg",
2280-
"proj_xz": "stack_Vol_projXZ.jpeg",
2267+
"proj_xz": "stack_Vol_projYZ.jpeg",
22812268
"alignment_quality": "0.5",
22822269
},
22832270
{

0 commit comments

Comments
 (0)