Reflection simulation#

The public reflection-simulation API has two symbols. It accepts package crystal and detector models and returns backend-neutral NumPy arrays.

See Simulate detector reflections for input selection, numerical behavior, and examples.

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/nm with 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_hkl does not have an integer dtype.

  • ValueError – If indexed_hkl has the wrong shape or contains (0, 0, 0).

Return type:

SimulationResult

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.

reciprocal contains reciprocal basis vectors as rows in 1/nm. Energy bounds are inclusive, and depth is 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 in 1/nm. For Miller index row hkl, the returned reciprocal vector is hkl @ 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:

SimulationResult

SimulationResult contains no backend objects or status flags. The implementation does not expose a backend choice or a fallback.