Analysis#
lauelab.analysis contains orientation, projection, coloring, and reflection-simulation functions. The functions accept NumPy-compatible arrays and return NumPy arrays or package data classes.
Reciprocal and orientation conventions#
See the results guide for the reciprocal-basis convention. lattice_params_to_reciprocal() takes cell lengths in nm and angles in degrees.
An orientation matrix maps vectors from the reference crystal basis to the measured basis. reciprocal_to_orientation() calculates that matrix as measured.T @ inv(reference.T). crystal_direction() applies the inverse orientation to a laboratory-frame direction.
Rotation matrices have shape (3, 3) and are dimensionless. orientation_to_rodrigues(), symmetry_reduce_orientation(), misorientation_matrix(), and crystal_direction() also accept a stack with shape (..., 3, 3) and return results with the matching leading shape. Rodrigues vectors use the dimensionless $\hat{a}\tan(\theta/2)$ convention. At the 180-degree singularity, orientation_to_rodrigues() clamps the effective angle to $\pi - 10^{-7}$ radians while retaining a deterministic rotation axis. Misorientation angles use degrees.
Lattice and orientation#
- lauelab.analysis.CUBIC_SYMMETRY: numpy.ndarray#
Cubic proper rotations with shape
(24, 3, 3).
- lauelab.analysis.HEXAGONAL_SYMMETRY: numpy.ndarray#
Hexagonal proper rotations with shape
(12, 3, 3).
- lauelab.analysis.lattice_params_to_reciprocal(a, b, c, alpha_deg, beta_deg, gamma_deg, *, space_group=None)[source]#
Return the native reciprocal basis as rows in inverse input-length units.
a,b, andcmust use one common length unit; the returned basis uses its inverse (normally1/nmin the public analysis API). Angles are in degrees, and reciprocal vectors include the2*pifactor.The direct basis follows native
setDirectRecip:cis parallel to positive z,blies in the yz plane, andacompletes a right-handed basis. Whenspace_groupis provided, native crystal-system constraints are applied before constructing the basis. For a trigonal space group, angles within the native tolerance of(90, 90, 120)select hexagonal axes; all other angles select rhombohedral axes.
- lauelab.analysis.reciprocal_to_orientation(reciprocal, reference_reciprocal)[source]#
Return the orientation matrix for measured and reference lattices.
reciprocalmay be one(3, 3)matrix or a stack with shape(..., 3, 3);reference_reciprocalis one matrix. The result has the shape ofreciprocal.
- lauelab.analysis.orientation_to_rodrigues(rotation)[source]#
Convert rotation matrices to
axis * tan(angle / 2).rotationmay be one(3, 3)matrix or a stack with shape(..., 3, 3); the result has shape(3,)or(..., 3).The Rodrigues magnitude is singular at 180 degrees. Near that singularity, the axis is recovered from the rotation eigenvectors and the effective angle is clamped to
pi - 1e-7radians, with the first nonzero axis component chosen positive. Unlike the Laue Portal’s zero-vector fallback, this retains a deterministic axis and decodes to approximately 180 degrees. A matrix with a non-finite entry maps to a vector ofNaN.A matrix within floating-point noise of the identity maps to the zero vector. Its antisymmetric part is as small as that of a 180-degree rotation, so the two are told apart by the trace (near 3 against near -1), not by the recovered angle, which
arccosamplifies near 1.
- lauelab.analysis.crystal_direction(rotation, lab_direction)[source]#
Express a lab-frame direction in crystal coordinates.
rotationmay be one(3, 3)matrix or a stack with shape(..., 3, 3); the result has the matching shape(..., 3). Every matrix in a stack is solved at once, so a singular matrix anywhere in the stack raisesnumpy.linalg.LinAlgError.
- lauelab.analysis.symmetry_operations(symmetry)[source]#
Return proper rotations for a supported symmetry name or space group.
- lauelab.analysis.symmetry_reduce_orientation(rotation, *, operations=None)[source]#
Return the symmetry-equivalent orientation nearest to identity.
rotationmay be one(3, 3)matrix or a stack with shape(..., 3, 3); the result has the same shape.
- lauelab.analysis.misorientation_matrix(rotation_a, rotation_b, *, operations=None)[source]#
Return the minimum-angle misorientation from
rotation_btorotation_a.rotation_amay be one(3, 3)matrix or a stack with shape(..., 3, 3);rotation_bis one matrix. The result has the shape ofrotation_a.
- lauelab.analysis.misorientation_angle(rotation_a, rotation_b, *, operations=None)[source]#
Return the minimum misorientation angle in degrees.
- lauelab.analysis.misorientation_from_reference(rotations, reference_index, *, operations=None)[source]#
Return Rodrigues vectors and angles relative to one orientation.
- lauelab.analysis.pairwise_misorientation(rotations, *, indices=None, operations=None)[source]#
Return pairs and corresponding misorientation angles.
The symmetry constants and arrays returned by symmetry_operations() contain proper rotation matrices. Cubic space groups are 195 through 230. Hexagonal space groups are 168 through 194.
Pole projection#
- class lauelab.analysis.SurfaceFrame(tilt, roll, normal, name=None)[source]
Right-handed orthonormal sample-surface coordinate frame.
- classmethod from_vectors(*, tilt, roll, normal, name=None)[source]
Construct and normalize a frame from three vectors.
- classmethod aps_34ide(name='normal')[source]
Return a named APS 34-ID-E surface frame.
- lauelab.analysis.cubic_hkl_family(hkl)[source]#
Return normalized symmetry-equivalent directions for a cubic HKL.
- lauelab.analysis.pole_figure_points(recip_lattices, hkl_family, *, surface=None)[source]#
Project reciprocal-lattice pole directions onto a surface frame.
- lauelab.analysis.pole_color_radius(center, angle_deg)[source]#
Convert an angular color radius to a stereographic radius.
Pole-figure points have shape (n, 2) and use dimensionless stereographic coordinates. Angular inputs use degrees. SurfaceFrame vectors are dimensionless laboratory-frame directions.
Coloring#
- lauelab.analysis.cubic_ipf_colors(directions)[source]#
Map crystal directions to cubic IPF RGB values in
[0, 1].
- lauelab.analysis.rodrigues_colors(vectors, *, max_angle_deg=None)[source]#
Map Rodrigues vectors to RGB values in
[0, 1].
- lauelab.analysis.hsv_position_colors(dx, dy, *, radius=1.0)[source]#
Map Cartesian offsets to an HSV wheel with white at its center.
- lauelab.analysis.closest_pole_colors(points, pattern_indices, count, *, center=(0.0, 0.0), radius=1.0)[source]#
Return each pattern’s HSV color from its closest projected pole.
- lauelab.analysis.cubic_ipf_key(resolution=256)[source]#
Return a cubic IPF reference triangle as a uint8 RGBA image.
- lauelab.analysis.hsv_key(resolution=256)[source]#
Return a circular HSV reference key as a uint8 RGBA image.
Color functions return RGB values in [0, 1] unless the function returns a reference image. Reference images have shape (height, width, 4), dtype numpy.uint8, and RGBA channel order. Angular color limits use degrees.
Reflection simulation#
- class lauelab.analysis.SimulationResult(hkl, q, detector_xy, energy_kev, relative_intensity)[source]
Immutable, aligned output from one detector reflection simulation.
- Parameters:
hkl (numpy.ndarray) – Integer Miller indices with shape
(n, 3).q (numpy.ndarray) – Reciprocal vectors in
1/nmwith shape(n, 3).detector_xy (numpy.ndarray) – Zero-based, unbinned full-detector
(x, y)pixels with shape(n, 2).energy_kev (numpy.ndarray) – Photon energies in keV with shape
(n,).relative_intensity (numpy.ndarray) – Uncalibrated JZT-derived relative intensities with shape
(n,).
Notes
All arrays are copied, normalized to 64-bit dtypes, and made read-only. Rows retain the deterministic order produced by
simulate_reflections().- missing_from(indexed_hkl)[source]
Return simulated directions absent from indexed Miller indices.
Positive scalar harmonics share a direction. Opposite signed Miller indices remain distinct Friedel directions.
- Parameters:
indexed_hkl (numpy.ndarray) – Integer Miller indices with shape
(m, 3). A one-dimensional empty integer array is also accepted.- Returns:
SimulationResult – A new immutable result. Its rows retain their original order.
- Raises:
TypeError – If
indexed_hkldoes not have an integer dtype.ValueError – If
indexed_hklhas the wrong shape or contains(0, 0, 0).
- Return type:
- lauelab.analysis.simulate_reflections(crystal, reciprocal, detector, *, energy_range_kev=(6.0, 30.0), depth=0.0)[source]
Simulate a complete, deterministic on-detector reflection pattern.
reciprocalcontains reciprocal basis vectors as rows in1/nm. Energy bounds are inclusive, anddepthis measured in micrometres. One strongest-intensity representative is retained per signed primitive harmonic direction. Equal intensities prefer lower energy and then lexicographically smaller HKL; final rows use the same tie-breakers after descending intensity. Floating sort keys are compared to 12 significant digits so numerical noise in symmetry-equivalent calculations reaches the integer HKL tie-breaker.- Parameters:
crystal (Crystal) – Package crystal description. The crystal must contain at least one atom site. Atom identity, fractional position, and occupancy enter the structure-factor calculation.
reciprocal (numpy.ndarray) – Finite, nonsingular reciprocal matrix with shape
(3, 3). Basis vectors occupy rows in1/nm. For Miller index rowhkl, the returned reciprocal vector ishkl @ reciprocal.detector (DetectorGeometry) – Metadata for one physical detector slot. Simulation uses its unbinned dimensions, physical size, translation, and rotation.
energy_range_kev (tuple[float, float]) – Two finite, positive, increasing energy bounds in keV. Both bounds are inclusive. The default is
(6.0, 30.0).depth (float) – Finite sample depth in micrometres. The default is
0.0.
- Returns:
SimulationResult – Complete direction-distinct reflections that intersect the selected detector within the requested energy interval. A valid simulation with no accepted reflections returns aligned empty arrays.
- Raises:
TypeError – If a package-owned object or numeric input has an unsupported type.
ValueError – If a scientific input is malformed, non-finite, or otherwise invalid.
RuntimeError – If the private simulation backend cannot load, execute, return valid numerical output, or complete within its private candidate limit.
- Return type:
Simulation uses reciprocal rows in 1/nm, photon energy in keV, sample depth in micrometres, and zero-based full-detector coordinates (x, y). See the reflection simulation reference and Simulate detector reflections for a complete workflow.