pyextal.acom.geometry

Reciprocal-space geometry for orientation determination.

Everything here works from the metric tensors the Bloch engine already parsed (SimParams.gmx, SimParams.gmxr), so no crystallography is duplicated and no external package is involved.

The one idea worth stating plainly: a Cartesian frame is built once from the direct metric, after which every question about lengths, angles and handedness is ordinary 3D vector algebra. Handedness matters — a left-handed in-plane basis produces a mirrored pattern that still “indexes”, which is exactly the class of error that is hard to spot by eye.

Functions

cartesian_frames(gmx)

Builds consistent direct and reciprocal Cartesian basis matrices.

zone_axis_cartesian(D, uvw)

Unit Cartesian vector along a direct-space zone axis.

inplane_basis(D, R, uvw, gg_hkl)

Builds a right-handed orthonormal basis of the zone's reciprocal plane.

project(R, hkl, e1, e2)

Projects reflections onto the in-plane basis.

excitation_error(R, hkl, n, bigk[, tilt])

Excitation error s_g for each reflection, in inverse Angstroms.

Module Contents

pyextal.acom.geometry.cartesian_frames(gmx)

Builds consistent direct and reciprocal Cartesian basis matrices.

D holds the direct lattice vectors as columns in a Cartesian frame, chosen so that D.T @ D == gmx. R holds the reciprocal lattice vectors, so that R.T @ R == inv(gmx). Because R = inv(D).T the two frames share an orientation, which makes the Miller-index dot product exact:

(R @ hkl) . (D @ uvw) == hkl . uvw
Parameters:

gmx (np.ndarray) – (3, 3) direct-space metric tensor.

Returns:

(D, R), each (3, 3).

Return type:

tuple[np.ndarray, np.ndarray]

pyextal.acom.geometry.zone_axis_cartesian(D, uvw)

Unit Cartesian vector along a direct-space zone axis.

Parameters:
  • D (np.ndarray) – Direct basis matrix from cartesian_frames().

  • uvw (array-like) – Zone axis as integer direct-space indices.

Returns:

(3,) unit vector.

Return type:

np.ndarray

pyextal.acom.geometry.inplane_basis(D, R, uvw, gg_hkl)

Builds a right-handed orthonormal basis of the zone’s reciprocal plane.

e1 runs along the projection of gg_hkl, e2 completes a right-handed set with the zone axis, so a reflection’s detector coordinates are (g . e1, g . e2) and never come out mirrored.

Parameters:
  • D (np.ndarray) – Direct basis matrix.

  • R (np.ndarray) – Reciprocal basis matrix.

  • uvw (array-like) – Zone axis, direct-space indices.

  • gg_hkl (array-like) – In-plane reference reflection defining the x axis.

Returns:

(e1, e2, n) unit Cartesian vectors; n is the zone axis.

Return type:

tuple[np.ndarray, np.ndarray, np.ndarray]

Raises:

ValueError – If gg_hkl has no component in the zone plane.

pyextal.acom.geometry.project(R, hkl, e1, e2)

Projects reflections onto the in-plane basis.

Parameters:
  • R (np.ndarray) – Reciprocal basis matrix.

  • hkl (np.ndarray) – (n, 3) Miller indices.

  • e1 (np.ndarray) – In-plane x unit vector.

  • e2 (np.ndarray) – In-plane y unit vector.

Returns:

(n, 2) in-plane coordinates in inverse Angstroms.

Return type:

np.ndarray

pyextal.acom.geometry.excitation_error(R, hkl, n, bigk, tilt=None)

Excitation error s_g for each reflection, in inverse Angstroms.

Uses the standard centre-of-Laue-circle expression s_g = -(2 K.g + |g|^2) / (2 |K + g|) with the incident wavevector taken along the zone axis unless a tilt is supplied.

Parameters:
  • R (np.ndarray) – Reciprocal basis matrix.

  • hkl (np.ndarray) – (n, 3) Miller indices.

  • n (np.ndarray) – Unit zone-axis Cartesian vector.

  • bigk (float) – Refraction-corrected |K|, from SimParams.bigK.

  • tilt (np.ndarray, optional) – (3,) tangential component of K in Miller indices; the untilted zone-axis case is used when None.

Returns:

(n,) excitation errors.

Return type:

np.ndarray