Last active
February 4, 2025 18:03
-
-
Save alisterburt/55d73dfa9c7513731fc7e34e00610302 to your computer and use it in GitHub Desktop.
works on per-tomogram table files and takes corresponding tomostar file name as input
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" | |
# /// | |
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'), | |
tomostar_file_name: str = typer.Option(..., '--tomostar', '-ts', help='tomostar file name'), | |
output_star_file: Path = typer.Option(..., '--output', '-o', help='output star file'), | |
): | |
# read table file | |
df = dynamotable.read(input_table_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 | |
) | |
# 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_file_name] * len(positions), | |
} | |
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