Created
February 3, 2025 18:15
-
-
Save alisterburt/e970ff7bdc3422bcc2fdbcb84eb974a3 to your computer and use it in GitHub Desktop.
standalone dynamo to warp particle metadata conversion, to run `uv run dynamo2warp.py`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# /// script | |
# requires-python = ">=3.11" | |
# dependencies = [ | |
# "dynamotable", | |
# "pandas", | |
# "scipy", | |
# "starfile", | |
# "typer", | |
# ] | |
# [tool.uv] | |
# exclude-newer = "2025-01-01T00:00:00Z" | |
# /// | |
import re | |
from pathlib import Path | |
import dynamotable | |
import pandas as pd | |
import starfile | |
import typer | |
from scipy.spatial.transform import Rotation as R | |
def cli( | |
input_table_file: Path = typer.Option(..., '--input', '--i', help='input table file'), | |
table_map_file: Path = typer.Option(..., '--table-map', '--tm', help='table map file'), | |
output_star_file: Path = typer.Option(..., '--output', '--o', help='output star file'), | |
): | |
# read table file | |
df = dynamotable.read(input_table_file, table_map_file=table_map_file) | |
# extract relevant metadata | |
positions = df[['x', 'y', 'z']].to_numpy() | |
shifts = df[['dx', 'dy', 'dz']].to_numpy() | |
dynamo_euler_angles = df[['tdrot', 'tilt', 'narot']].to_numpy() | |
# convert dynamo euler angles into rotation matrices in which the | |
# columns are the particle x/y/z vectors in the tomogram | |
particle_rotation_matrices = R.from_euler( | |
angles=dynamo_euler_angles, seq='zxz', degrees=True | |
).inv().as_matrix() | |
# construct particle metadata for RELION | |
positions += shifts | |
relion_euler_angles = R.from_matrix(particle_rotation_matrices).inv().as_euler( | |
seq='ZYZ', degrees=True | |
) | |
tomogram_files = df['tomo_file'].to_list() | |
tomostar_files = [ | |
re.sub(pattern=r".mrc_\d+.\d+Apx.mrc", repl=".tomostar", string=tomogram_file) | |
for tomogram_file | |
in tomogram_files | |
] | |
# write out RELION style star file compatible with Warp | |
star_data = { | |
'rlnCoordinateX': positions[:, 0], | |
'rlnCoordinateY': positions[:, 1], | |
'rlnCoordinateZ': positions[:, 2], | |
'rlnAngleRot': relion_euler_angles[:, 0], | |
'rlnAngleTilt': relion_euler_angles[:, 1], | |
'rlnAnglePsi': relion_euler_angles[:, 2], | |
'rlnMicrographName': tomostar_files, | |
} | |
starfile.write(pd.DataFrame(star_data), output_star_file) | |
if __name__ == "__main__": | |
app = typer.Typer(add_completion=False) | |
app.command(no_args_is_help=True)(cli) | |
app() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment