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. 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.
- lauelab.analysis.orientation_to_rodrigues(rotation)[source]#
Convert a 3 by 3 rotation matrix to
axis * tan(angle / 2).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.
- lauelab.analysis.crystal_direction(rotation, lab_direction)[source]#
Express a lab-frame direction in crystal coordinates.
- 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.
- lauelab.analysis.misorientation_matrix(rotation_a, rotation_b, *, operations=None)[source]#
Return the minimum-angle misorientation from
rotation_btorotation_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.