graintrace.orientation_helper#

Orientation math helpers: Euler/matrix/MRP/quaternion conversions and misorientation.

graintrace.orientation_helper.euler_to_matrix(euler, convention='bunge', angle_type='degrees')[source]#

Convert Euler angles to rotation matrices.

Bunge angles are applied as a Z-X-Z composition of MRP.from_axis_angle rotations; the matrix comes from euler_rodrigues.

Parameters:
  • euler (ndarray | list | Tensor) – (…, 3) Euler angles.

  • convention (str) – ‘bunge’, ‘kocks’, or ‘roe’.

  • angle_type (str) – ‘degrees’ or ‘radians’.

Returns:

(…, 3, 3) rotation matrices.

Return type:

Tensor

graintrace.orientation_helper.matrix_to_euler(M, convention='bunge', angle_type='degrees')[source]#

Convert rotation matrices to Euler angles (inverse of euler_to_matrix()).

Parameters:
  • M (Tensor) – (…, 3, 3) rotation matrices.

  • convention (str) – ‘bunge’, ‘kocks’, or ‘roe’.

  • angle_type (str) – ‘degrees’ or ‘radians’.

Returns:

(…, 3) Euler angles.

Return type:

Tensor

graintrace.orientation_helper.matrix_to_mrp(M)[source]#

Convert rotation matrices (…, 3, 3) to neml2 v3 MRP (…, 3).

Parameters:

M (ndarray | Tensor)

Return type:

Tensor

graintrace.orientation_helper.euler_to_mrp(euler, convention='bunge', angle_type='degrees')[source]#

Convert Euler angles to neml2 v3 modified Rodrigues parameters (…, 3).

Parameters:
Return type:

Tensor

graintrace.orientation_helper.quat_to_matrix(q)[source]#

Convert a scalar-first unit quaternion (…, 4) (w, x, y, z) to a rotation matrix (…, 3, 3), via neml2 quaternion_rotation_matrix.

Parameters:

q (Tensor)

Return type:

Tensor

graintrace.orientation_helper.mrp_to_matrix(p)[source]#

Convert neml2 v3 MRP orientations (…, 3) to rotation matrices (…, 3, 3).

Parameters:

p (ndarray | list | Tensor)

Return type:

Tensor

graintrace.orientation_helper.mrp_to_euler(p, convention='bunge', angle_type='degrees')[source]#

Convert neml2 v3 MRP orientations (…, 3) to Euler angles (…, 3).

Parameters:
Return type:

Tensor

graintrace.orientation_helper.perturb_orientation(euler, sigma_deg, convention='bunge', angle_type='degrees', rng=None)[source]#

Apply an independent random misorientation to each orientation.

Each orientation is composed with a random rotation about a uniformly distributed axis, with rotation angle drawn from N(0, sigma_deg) (degrees). sigma_deg is therefore the standard deviation of the applied rotation angle; the resulting fundamental-zone misorientation magnitude is |angle|. This is a proper (gimbal-free) perturbation, unlike scaling each Euler angle independently. sigma_deg <= 0 returns the input orientations unchanged.

Parameters:
  • euler (ndarray | list | Tensor) – (…, 3) Euler angles.

  • sigma_deg (float) – std of the applied rotation angle, in degrees.

  • convention (str) – ‘bunge’, ‘kocks’, or ‘roe’.

  • angle_type (str) – ‘degrees’ or ‘radians’ (applies to both input and output).

  • rng (Generator | None) – optional numpy Generator for reproducibility (default: np.random).

Returns:

(…, 3) perturbed Euler angles in the same convention/units.

Return type:

Tensor

graintrace.orientation_helper.symmetry_operators(symmetry)[source]#

Crystal symmetry operators as rotation matrices (nops, 3, 3).

Parameters:

symmetry (str)

Return type:

Tensor

graintrace.orientation_helper.misorientation_matrix(R1, R2, symmetry='1', angle_type='degrees')[source]#

Misorientation angle between two sets of rotation matrices under symmetry.

Parameters:
  • R1 (Tensor) – (N, 3, 3) rotation matrices.

  • R2 (Tensor) – (N, 3, 3) rotation matrices.

  • symmetry (str) – crystal symmetry in orbifold notation.

  • angle_type (str) – ‘degrees’ or ‘radians’ for the returned angle.

Returns:

(N,) misorientation angles.

Return type:

Tensor

graintrace.orientation_helper.move_to_fundamental_zone(R, symmetry='1')[source]#

Reduce rotation matrices to the fundamental zone under crystal symmetry.

Picks, per orientation, the symmetry-equivalent with the smallest rotation angle (largest trace of O @ R).

Parameters:
  • R (Tensor) – (…, 3, 3) rotation matrices.

  • symmetry (str) – crystal symmetry in orbifold notation.

Returns:

(…, 3, 3) reduced rotation matrices.

Return type:

Tensor

graintrace.orientation_helper.average_orientation(euler, weights=None, convention='bunge', angle_type='degrees', symmetry='1')[source]#

Symmetry-aware weighted mean of a set of Euler orientations.

Every orientation is brought into the symmetry-equivalent closest to the highest-weight orientation, matrix-averaged (weighted), and re-projected onto SO(3) via SVD (the polar/chordal mean); the result is converted back to Euler angles in the given convention/units.

Parameters:
  • euler (ndarray | list | Tensor) – (N, 3) Euler angles, or (3,) for a single orientation.

  • weights (ndarray | list | Tensor | None) – (N,) non-negative weights (default: uniform).

  • convention (str) – ‘bunge’, ‘kocks’, or ‘roe’.

  • angle_type (str) – ‘degrees’ or ‘radians’.

  • symmetry (str) – crystal symmetry in orbifold notation.

Returns:

(3,) averaged Euler angles in the given convention/units.

Return type:

Tensor

graintrace.orientation_helper.misorientation(e1, e2, angle_convention='bunge', angle_type='degrees', symmetry='1')[source]#

Compute misorientation between two sets of Euler angles

Parameters:
  • e1 (ndarray | list) – Nx3 array of Euler angles

  • e2 (ndarray | list) – Nx3 array of Euler angles

  • angle_convention (str)

  • angle_type (str)

  • symmetry (str)

Keyword Arguments:
  • angle_convention (str) – ‘kocks’, ‘bunge’, or ‘roe’ (default: ‘kocks’)

  • angle_type (str) – ‘degrees’ or ‘radians’ (default: ‘degrees’)

  • symmetry (str) – crystal symmetry in orbifold notation (default: ‘1’)

Returns:

Nx1 array of misorientation angles

Return type:

Tensor

graintrace.orientation_helper.load_orientation_matrices(df, field='O')[source]#

Load per-row rotation matrices (…, 3, 3) from a dataframe.

Storage is assumed row-major: {field}{i}{j} maps to M[i-1, j-1] (and the field=None positional path reshapes the first 9 columns row-major). All in-repo producers (NEPER reconstruction.ori, experiment_rotation_helper) write row-major; a column-major producer would silently yield the transpose.

Parameters:
  • df (pd.DataFrame) – Dataframe containing orientation data.

  • field (str, optional) – Column prefix for the 3x3 orientation matrix (columns {field}{i}{j}, row-major). If None, the first 9 columns are used positionally (row-major). Defaults to ‘O’.

Returns:

(n, 3, 3) rotation matrices.

Return type:

torch.Tensor

graintrace.orientation_helper.load_orientations(df, field='O')[source]#

Load orientations as neml2 v3 modified Rodrigues parameters (n, 3).

Parameters:
  • df (pd.DataFrame) – Dataframe containing orientation data.

  • field (str, optional) – Column name for orientation matrix. Defaults to ‘O’.

Returns:

(n, 3) neml2 MRP orientations.

Return type:

torch.Tensor

graintrace.orientation_helper.load_orientations_mrp(df, field='O')#

Load orientations as neml2 v3 modified Rodrigues parameters (n, 3).

Parameters:
  • df (pd.DataFrame) – Dataframe containing orientation data.

  • field (str, optional) – Column name for orientation matrix. Defaults to ‘O’.

Returns:

(n, 3) neml2 MRP orientations.

Return type:

torch.Tensor

graintrace.orientation_helper.matrix_to_quat(M)[source]#

Convert rotation matrices (…, 3, 3) to scalar-first unit quaternions (…, 4) (w, x, y, z), via neml2 (MRP.from_matrix -> to_quaternion).

Parameters:

M (Tensor)

Return type:

Tensor

graintrace.orientation_helper.load_strains(df, field='eKen', factor=1e-06)[source]#

Load strains from dataframe and convert to torch tensor.

Parameters:
  • df (pd.DataFrame) – Dataframe containing strain data.

  • field (str, optional) – Column name for strain data. Defaults to ‘eKen’.

  • factor (float, optional) – Conversion factor (microstrain->strain). Defaults to 1e-6.

Returns:

Tensor containing strain data.

Return type:

torch.Tensor

graintrace.orientation_helper.load_weights(df, field='GrainRadius')[source]#

Load the grain volumes and convert to a torch tensor of weights.

Parameters:
  • df (pd.DataFrame) – Dataframe containing grain volume data.

  • field (str, optional) – Column name for grain volume data. Defaults to ‘GrainRadius’.

Returns:

Normalized weight tensor.

Return type:

torch.Tensor