Representing poses¤
cryojax
provides different parameterizations for the pose of a structure. These are captured through the abstract base class called AbstractPose
.
Rotation and translation conventions
Pose transformations in cryojax
can be captured by the equation
where \(\vec{x}'\) and \(\vec{x}\) are the 3D coordinate vectors in the rotated and unrotated frames, and \(R\) and \(\vec{t} = (t_x, t_y, 0)\) are the rotation and in-plane translation vector.
Standard softwares such as RELION and cisTEM define the rotation and translation to "undo" the observed pose. This can be captured by a translation to the center, followed by a rotation:
When \(R^* = R^T\) and \(\vec{t}^* = -\vec{t}\), this equation can be inverted for \(\vec{x}'\) to recover the cryoJAX convention.
Additional considerations are required to convert between RELION and cisTEM euler angles since this is a composition
of three rotations. See the EulerAnglePose
documentation for more information.
Degrees vs radians conventions
Angular quantities in cryojax
are always in degrees.
Therefore concrete classes of the AbstractPose
have
angles in degrees, e.g.
import cryojax.simulator as cxs
phi_in_degrees, theta_in_degrees, psi_in_degrees = 10.0, 30.0, 40.0
pose = cxs.EulerAnglePose(
phi_angle=phi_in_degrees,
theta_angle=theta_in_degrees,
psi_angle=psi_in_degrees,
)
cryojax.simulator.AbstractPose
cryojax.simulator.AbstractPose
¤
Base class for the image pose. Subclasses will choose a
particular convention for parameterizing the rotation by
overwriting the AbstractPose.rotation
property.
cryojax.simulator.AbstractPose.rotate_coordinates(coordinate_grid_or_list: Float[Array, 'z_dim y_dim x_dim 3'] | Float[Array, 'size 3'], inverse: bool = False) -> Float[Array, 'z_dim y_dim x_dim 3'] | Float[Array, 'size 3']
¤
Rotate a 3D coordinate system.
Arguments:
coordinate_grid_or_list
: The 3D coordinate system to rotate. This can either be a list of coordinates of shape(N, 3)
or a grid of coordinates(N1, N2, N3, 3)
.inverse
: IfTrue
, compute the inverse rotation (i.e. rotation by the matrix \(R^T\), where \(R\) is the rotation matrix).
Returns:
The rotated version of coordinate_grid_or_list
.
cryojax.simulator.AbstractPose.offset_in_angstroms: Float[Array, 2] | Float[Array, 3]
cached
property
¤
The in-plane translation vector, where the origin in taken to be in the center of the imaging plane.
cryojax.simulator.AbstractPose.rotation: SO3
abstractmethod
cached
property
¤
Generate an SO3
object from a particular angular
parameterization.
cryojax.simulator.AbstractPose.from_rotation(rotation: SO3) -> Self
abstractmethod
classmethod
¤
Construct an AbstractPose
from an SO3
object.
cryojax.simulator.AbstractPose.from_rotation_and_translation(rotation: SO3, offset_in_angstroms: Float[Array, 2] | Float[Array, 3]) -> Self
classmethod
¤
Construct an AbstractPose
from an SO3
object and a
translation vector.
cryojax.simulator.EulerAnglePose
¤
An AbstractPose
represented by Euler angles.
Angles are given in degrees, and the sequence of rotations is a
zyz extrinsic rotation, with phi_angle
as the first euler angle,
theta_angle
as the second, and psi_angle
is the third.
Converting to RELION and FREALIGN convention
RELION/FREALIGN convention is that the euler angles represent a zyz intrinsic rotation that "undoes" the rotation in the image. cryoJAX defines its convention to be a zyz extrinsic rotation that generates the pose in the image. In order to convert to the RELION/FREALIGN convention, simply negate each euler angle.
cryojax.simulator.EulerAnglePose.__init__(offset_x_in_angstroms: float | Float[Array, ''] = 0.0, offset_y_in_angstroms: float | Float[Array, ''] = 0.0, phi_angle: float | Float[Array, ''] = 0.0, theta_angle: float | Float[Array, ''] = 0.0, psi_angle: float | Float[Array, ''] = 0.0, *, offset_z_in_angstroms: Optional[float | Float[Array, '']] = None)
¤
Arguments:
offset_x_in_angstroms
: In-plane translation in x direction.offset_y_in_angstroms
: In-plane translation in y direction.phi_angle
: Angle to rotate about first rotation axis, which is the z axis.theta_angle
: Angle to rotate about second rotation axis, which is the y axis.psi_angle
: Angle to rotate about third rotation axis, which is the z axis.offset_z_in_angstroms
: Out-of-plane translation in z direction.
cryojax.simulator.QuaternionPose
¤
An AbstractPose
represented by unit quaternions.
cryojax.simulator.QuaternionPose.__init__(offset_x_in_angstroms: float | Float[Array, ''] = 0.0, offset_y_in_angstroms: float | Float[Array, ''] = 0.0, wxyz: tuple[float, float, float, float] | Float[np.ndarray, 4] | Float[Array, 4] = (1.0, 0.0, 0.0, 0.0), *, offset_z_in_angstroms: Optional[float | Float[Array, '']] = None)
¤
Arguments:
offset_x_in_angstroms
: In-plane translation in x direction.offset_y_in_angstroms
: In-plane translation in y direction.wxyz
: The quaternion, represented as a vector \(\mathbf{q} = (q_w, q_x, q_y, q_z)\).offset_z_in_angstroms
: Out-of-plane translation in z direction.
cryojax.simulator.AxisAnglePose
¤
An AbstractPose
parameterized in the axis-angle representation.
The axis-angle representation parameterizes elements of the so3 algebra, which are skew-symmetric matrices, with the euler vector \(\boldsymbol{\omega} = (\omega_x, \omega_y, \omega_z)\). The magnitude of this vector is the angle, and the unit vector is the axis.
In a SO3
object, the euler vector is mapped to SO3 group elements using
the matrix exponential.
cryojax.simulator.AxisAnglePose.__init__(offset_x_in_angstroms: float | Float[Array, ''] = 0.0, offset_y_in_angstroms: float | Float[Array, ''] = 0.0, euler_vector: tuple[float, float, float] | Float[np.ndarray, 3] | Float[Array, 3] = (0.0, 0.0, 0.0), *, offset_z_in_angstroms: Optional[float | Float[Array, '']] = None)
¤
Arguments:
offset_x_in_angstroms
: In-plane translation in x direction.offset_y_in_angstroms
: In-plane translation in y direction.euler_vector
: The axis-angle parameterization, represented with the euler vector \(\boldsymbol{\omega}\).offset_z_in_angstroms
: Out-of-plane translation in z direction.