Overview
napari-tomoslice is a tool for interactively annotating geometrical structures in cryo-ET data and generating particle poses from these geometrical annotations for subtomogram averaging.
With napari-tomoslice you can
- Annotate geometrical structures in napari
- Generate poses from the geometrical annotations
- Convert poses for your favourite subtomogram averaging package
napari-tomoslice allows you to annotate points, spheres, paths and dipoles. Poses can be sampled in a number of ways from each annotation type, for a complete list see: pose generation
Poses can be easily converted into Relion STAR file format or Dynamo table format
Running napari-tomoslice
napari-tomoslice can simply be run using uvx with:
uvx napari-tomoslice
uv can be installed with:
curl -LsSf https://astral.sh/uv/install.sh | sh
How to install and use uv ?
More detailed information on how to install uv and how to use uvx can be found on the uv documentation.
Examples
Example Data
Data used in the examples can be downloaded from zenodo
Visualize the results
Results from generate-poses and convert-poses can be visualized with their corresponding tomogram with the example script below:
# /// script
# dependencies = [
# "mrcfile",
# "starfile",
# "napari[pyqt5]",
# "numpy",
# "scipy",
# ]
# ///
import mrcfile
import napari
import numpy as np
import starfile
from scipy.spatial.transform import Rotation as R
tomogram_file = 'tomograms/microtubule.mrc'
particles_file = 'tomograms/backbone.star' # STAR file output from generate-poses or convert-poses
with mrcfile.open(tomogram_file) as mrc:
tomogram = mrc.data.copy()
df = starfile.read(particles_file)
xyz = df[['x', 'y', 'z']].to_numpy()
# xyz_relion = df[['rlnCoordinateX', 'rlnCoordinateY', 'rlnCoordinateZ']].to_numpy()
euler_angles = df[['rot', 'tilt', 'psi']].to_numpy()
# euler_angles_relion = df[['rlnAngleRot', 'rlnAngleTilt', 'rlnAnglePsi']].to_numpy()
rotations = R.from_euler(seq='ZYZ', angles=euler_angles, degrees=True).inv()
rotated_z_vectors = rotations.apply([0, 0, 1])
viewer = napari.Viewer(ndisplay=3)
vectors = np.zeros((rotated_z_vectors.shape[0], 2, 3))
vectors[:, 0, :] = xyz[:, ::-1]
vectors[:, 1, :] = rotated_z_vectors[:, ::-1]
viewer.add_image(tomogram, blending='translucent_no_depth', colormap='gray_r')
viewer.add_points(xyz[:, ::-1], face_color='cornflowerblue', size=10)
viewer.add_vectors(vectors, length=12, edge_color='orange', edge_width=4)
napari.run()