rheedium.types¶
JAX PyTree data structures for crystallographic and RHEED simulation data.
Custom types and data structures for RHEED simulation.
Extended Summary¶
This module defines JAX-compatible data structures for representing crystal structures, RHEED patterns, and other simulation data. All types are PyTrees that support JAX transformations and automatic differentiation.
Routine Listings¶
CrystalStructureJAX-compatible crystal structure with fractional and Cartesian coordinates.
DetectorGeometryConfiguration for RHEED detector geometry (tilt, curvature, offsets).
ElectronBeamComplete specification of an electron beam for RHEED simulation.
EwaldDataAngle-independent Ewald sphere data for RHEED simulation.
KirklandParametersStructured Kirkland coefficients for one element.
OrientationDistributionProbability distribution over azimuthal domain orientations.
PotentialSlicesJAX-compatible data structure for representing multislice potential data.
RHEEDImageContainer for RHEED image data with pixel coordinates and intensity values.
RHEEDPatternContainer for RHEED diffraction pattern data with detector points and intensities.
SlicedCrystalJAX-compatible crystal structure sliced for multislice simulation.
SizeDistributionProbability distribution over coherent domain sizes.
SurfaceConfigConfiguration for surface atom identification method and parameters.
XYZDataA PyTree for XYZ file data with atomic positions and metadata.
create_crystal_structure()Factory function to create CrystalStructure instances.
create_electron_beam()Factory function to create ElectronBeam instances.
create_ewald_data()Factory function to create EwaldData instances.
create_orientation_distribution()Canonical factory for orientation distributions.
create_discrete_orientation()Create a sharp rotational-variant distribution.
create_gaussian_orientation()Create a Gaussian mosaic orientation distribution.
create_kirkland_parameters()Factory function to create KirklandParameters instances.
create_lognormal_size()Create a lognormal domain-size distribution.
create_mixed_orientation()Create discrete orientation variants with mosaic broadening.
create_potential_slices()Factory function to create PotentialSlices instances.
create_rheed_image()Factory function to create RHEEDImage instances.
create_rheed_pattern()Factory function to create RHEEDPattern instances.
create_sliced_crystal()Factory function to create SlicedCrystal instances.
create_xyz_data()Factory function to create XYZData instances.
discretize_orientation()Convert an orientation distribution to quadrature samples.
discretize_orientation_static()Python-branching orientation discretization for non-JIT use.
identify_surface_atoms()Identify surface atoms using configurable methods.
integrate_over_orientation()Simulate and incoherently average over orientation samples.
float_jax_imageType alias for float-valued 2D JAX image arrays.
float_np_imageType alias for float-valued 2D numpy image arrays.
int_jax_imageType alias for integer-valued 2D JAX image arrays.
int_np_imageType alias for integer-valued 2D numpy image arrays.
non_jax_numberUnion type for non-JAX numeric values (int or float).
scalar_boolUnion type for scalar boolean values (bool or JAX scalar array).
scalar_floatUnion type for scalar float values (float or JAX scalar array).
scalar_intUnion type for scalar integer values (int or JAX scalar array).
scalar_numUnion type for scalar numeric values (int, float, or JAX scalar array).
AMU_TO_KGAtomic mass unit to kg conversion factor.
BOLTZMANN_CONSTANT_JKBoltzmann constant in J/K.
ELECTRON_MASS_KGElectron rest mass in kg.
ELEMENTARY_CHARGE_CElementary charge in C.
H_OVER_SQRT_2ME_ANG_VSQRTElectron wavelength prefactor h / sqrt(2 m_e e) in Ang V^0.5.
HBAR_JSReduced Planck constant in J s.
M2_TO_ANG2Square metres to square angstroms conversion factor.
PLANCK_CONSTANT_JSPlanck constant h in J s.
RELATIVISTIC_COEFF_PER_VRelativistic correction coefficient e / (2 m_e c^2) in 1/V.
SPEED_OF_LIGHT_MSSpeed of light in vacuum in m/s.
Notes
Every PyTree has a corresponding factory function to create the instance. This is because beartype does not support type checking of dataclasses.
- class rheedium.types.ElectronBeam(energy_kev: float | Float[Array, ''] = 20.0, energy_spread_ev: float | Float[Array, ''] = 0.5, angular_divergence_mrad: float | Float[Array, ''] = 0.5, coherence_length_transverse_angstrom: float | Float[Array, ''] = 500.0, coherence_length_longitudinal_angstrom: float | Float[Array, ''] = 1000.0, spot_size_um: Float[Array, '2'] = Array([100., 50.], dtype=float64))[source]¶
Bases:
NamedTupleComplete specification of an electron beam for RHEED simulation.
This PyTree captures all physical parameters of the electron source needed for instrument-broadened RHEED pattern simulation. Typical RHEED guns have angular divergence 0.1–1 mrad, energy spread 0.1–1 eV, and transverse coherence lengths 100–1000 Angstroms.
- energy_spread_ev¶
1-sigma energy spread in eV. Typical: 0.1–1.0 eV. Controls longitudinal coherence and streak position variation. Default: 0.5
- Type:
- angular_divergence_mrad¶
1-sigma angular divergence in milliradians. Typical: 0.1–1.0 mrad. Controls transverse coherence and streak width. Default: 0.5
- Type:
- coherence_length_transverse_angstrom¶
Transverse coherence length in Angstroms. Typical: 100–1000. Limits the angular range over which diffraction is coherent. Default: 500.0
- Type:
- coherence_length_longitudinal_angstrom¶
Longitudinal coherence length in Angstroms. Related to energy spread by L_l = lambda^2 / delta_lambda. Default: 1000.0
- Type:
- spot_size_um¶
Beam footprint [width, height] on surface in micrometers. RHEED illuminates mm-scale areas; this sets the incoherent averaging domain. Default: [100.0, 50.0]
- Type:
Float[Array,"2"]
Notes
This class is registered as a PyTree node, making it compatible with JAX transformations like jit, grad, and vmap. All continuous parameters (energy, spread, divergence, coherence lengths) are differentiable. The spot_size_um is also differentiable but rarely optimized in practice.
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> >>> beam = rh.types.create_electron_beam( ... energy_kev=15.0, ... angular_divergence_mrad=0.3, ... energy_spread_ev=0.2, ... )
- spot_size_um: Float[Array, '2']¶
Alias for field number 5
- rheedium.types.create_electron_beam(energy_kev: float | Float[Array, ''] = 20.0, energy_spread_ev: float | Float[Array, ''] = 0.5, angular_divergence_mrad: float | Float[Array, ''] = 0.5, coherence_length_transverse_angstrom: float | Float[Array, ''] = 500.0, coherence_length_longitudinal_angstrom: float | Float[Array, ''] = 1000.0, spot_size_um: Float[Array, '2'] = jnp.array([100.0, 50.0])) ElectronBeam[source]¶
Create an ElectronBeam instance with data validation.
- Parameters:
energy_kev (
Union[float,Float[Array, '']], default:20.0) – Nominal accelerating voltage in keV. Must be in [5, 100]. Default: 20.0energy_spread_ev (
Union[float,Float[Array, '']], default:0.5) – 1-sigma energy spread in eV. Must be non-negative. Default: 0.5angular_divergence_mrad (
Union[float,Float[Array, '']], default:0.5) – 1-sigma angular divergence in milliradians. Must be non-negative. Default: 0.5coherence_length_transverse_angstrom (
Union[float,Float[Array, '']], default:500.0) – Transverse coherence length in Angstroms. Must be positive. Default: 500.0coherence_length_longitudinal_angstrom (
Union[float,Float[Array, '']], default:1000.0) – Longitudinal coherence length in Angstroms. Must be positive. Default: 1000.0spot_size_um (
Float[Array, '2'], default:jnp.array([100.0, 50.0])) – Beam footprint [width, height] in micrometers. Both components must be positive. Default: [100.0, 50.0]
- Returns:
validated_beam – Validated ElectronBeam instance.
- Return type:
Notes
Cast all inputs to float64 JAX arrays.
Validate energy_kev is in [5, 100] keV.
Validate energy_spread_ev >= 0.
Validate angular_divergence_mrad >= 0.
Validate coherence lengths are positive.
Validate spot_size_um components are positive.
Return constructed ElectronBeam.
Examples
>>> import rheedium as rh >>> >>> beam = rh.types.create_electron_beam(energy_kev=15.0) >>> beam.energy_kev Array(15., dtype=float64)
- class rheedium.types.CrystalStructure(frac_positions: Num[Array, 'N 4'], cart_positions: Num[Array, 'N 4'], cell_lengths: Num[Array, '3'], cell_angles: Num[Array, '3'])[source]¶
Bases:
NamedTupleJAX-compatible Pytree with fractional and Cartesian coordinates.
This PyTree represents a crystal structure containing atomic positions in both fractional and Cartesian coordinate systems, along with unit cell parameters. It’s designed for efficient crystal structure calculations and electron diffraction simulations.
- frac_positions¶
Array of shape (n_atoms, 4) containing atomic positions in fractional coordinates. Each row contains [x, y, z, atomic_number] where x, y, z are fractional coordinates in the unit cell (range [0,1]) and atomic_number is the integer atomic number (Z) of the element.
- Type:
Num[Array,"N 4"]
- cart_positions¶
Array of shape (n_atoms, 4) containing atomic positions in Cartesian coordinates. Each row contains [x, y, z, atomic_number] where x, y, z are Cartesian coordinates in Ångstroms and atomic_number is the integer atomic number (Z).
- Type:
Num[Array,"N 4"]
- cell_lengths¶
Unit cell lengths [a, b, c] in Ångstroms.
- Type:
Num[Array,"3"]
- cell_angles¶
Unit cell angles [α, β, γ] in degrees, where α is the angle between b and c, β is the angle between a and c, and γ is the angle between a and b.
- Type:
Num[Array,"3"]
- This class is registered as a PyTree node, making it compatible with JAX
- transformations like jit, grad, and vmap. All data is immutable and stored
- in JAX arrays for efficient computation.
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> >>> # Create crystal structure for simple cubic lattice >>> frac_pos = jnp.array([[0.0, 0.0, 0.0, 6]]) # Carbon atom at origin >>> cart_pos = jnp.array([[0.0, 0.0, 0.0, 6]]) # Same in Cartesian >>> cell_lengths = jnp.array([3.57, 3.57, 3.57]) # Diamond lattice >>> cell_angles = jnp.array([90.0, 90.0, 90.0]) # Cubic angles >>> crystal = rh.types.create_crystal_structure( ... frac_positions=frac_pos, ... cart_positions=cart_pos, ... cell_lengths=cell_lengths, ... cell_angles=cell_angles, ... )
- class rheedium.types.EwaldData(wavelength_ang: Float[Array, ''], k_magnitude: Float[Array, ''], sphere_radius: Float[Array, ''], recip_vectors: Float[Array, '3 3'], hkl_grid: Int[Array, 'N 3'], g_vectors: Float[Array, 'N 3'], g_magnitudes: Float[Array, 'N'], structure_factors: Complex[Array, 'N'], intensities: Float[Array, 'N'])[source]¶
Bases:
NamedTupleAngle-independent Ewald sphere data for RHEED simulation.
This PyTree contains pre-computed reciprocal lattice geometry and structure factors that depend only on crystal structure and beam voltage, not on beam orientation angles. This enables efficient reuse when scanning beam azimuth or incidence angle.
- wavelength_ang¶
Relativistic electron wavelength in Ångstroms.
- Type:
Float[Array,""]
- k_magnitude¶
Magnitude of electron wavevector \(|k| = 2\pi/\lambda\) in 1/Ångstroms.
- Type:
Float[Array,""]
- sphere_radius¶
Ewald sphere radius in 1/Ångstroms (equals k_magnitude).
- Type:
Float[Array,""]
- recip_vectors¶
Reciprocal lattice basis vectors [b₁, b₂, b₃] as rows.
- Type:
Float[Array,"3 3"]
- hkl_grid¶
Miller indices (h, k, l) for all reciprocal lattice points.
- Type:
Int[Array,"N 3"]
- g_vectors¶
Reciprocal lattice vectors G in 1/Ångstroms.
- Type:
Float[Array,"N 3"]
- g_magnitudes¶
Magnitudes \(|G|\) for each reciprocal lattice vector.
- Type:
Float[Array,"N"]
- structure_factors¶
Complex structure factors F(G) for each reciprocal lattice point.
- Type:
Complex[Array,"N"]
- intensities¶
Kinematic diffraction intensities \(I(G) = |F(G)|^2\).
- Type:
Float[Array,"N"]
Notes
This class is registered as a PyTree node for JAX compatibility. The structure factors include Kirkland atomic form factors and Debye-Waller thermal damping.
Examples
>>> import rheedium as rh >>> crystal = rh.inout.parse_cif("MgO.cif") >>> ewald = rh.ucell.build_ewald_data( ... crystal=crystal, ... voltage_kv=15.0, ... hmax=3, ... kmax=3, ... lmax=2, ... ) >>> print(f"Sphere radius: {ewald.sphere_radius:.2f} 1/Å")
- class rheedium.types.KirklandParameters(lorentzian_amplitudes: Float[Array, '3'], lorentzian_scales: Float[Array, '3'], gaussian_amplitudes: Float[Array, '3'], gaussian_scales: Float[Array, '3'])[source]¶
Bases:
NamedTupleStructured Kirkland coefficients for one element.
This PyTree holds the three Lorentzian and three Gaussian amplitude/scale pairs from the Kirkland parameterization of electron scattering factors.
- lorentzian_amplitudes¶
Lorentzian amplitude coefficients (a_1, a_2, a_3).
- Type:
Float[Array,"3"]
- lorentzian_scales¶
Lorentzian scale coefficients (b_1, b_2, b_3).
- Type:
Float[Array,"3"]
- gaussian_amplitudes¶
Gaussian amplitude coefficients (c_1, c_2, c_3).
- Type:
Float[Array,"3"]
- gaussian_scales¶
Gaussian scale coefficients (d_1, d_2, d_3).
- Type:
Float[Array,"3"]
- This class is registered as a PyTree node, making it compatible
- with JAX transformations like jit, grad, and vmap. All fields are
- JAX arrays and are stored as leaf nodes.
- lorentzian_amplitudes: Float[Array, '3']¶
Alias for field number 0
- lorentzian_scales: Float[Array, '3']¶
Alias for field number 1
- gaussian_amplitudes: Float[Array, '3']¶
Alias for field number 2
- gaussian_scales: Float[Array, '3']¶
Alias for field number 3
- class rheedium.types.PotentialSlices(slices: Float[Array, 'n_slices height width'], slice_thickness: float | Float[Array, ''], x_calibration: float | Float[Array, ''], y_calibration: float | Float[Array, ''])[source]¶
Bases:
NamedTupleJAX-compatible multislice potential data for electron beam propagation.
This PyTree represents discretized potential data used in multislice electron diffraction calculations. It contains 3D potential slices with associated calibration information for accurate physical modeling.
- slices¶
3D array containing projected-potential data for each slice. First dimension indexes slices, second and third dimensions are spatial coordinates. Units: Volt-Angstrom. These are projected slice potentials, not volumetric potentials.
- Type:
Float[Array,"n_slices height width"]
- slice_thickness¶
Thickness of each slice in Ångstroms. Determines the z-spacing between consecutive slices.
- Type:
- x_calibration¶
Real space calibration in the x-direction in Ångstroms per pixel. Converts pixel coordinates to physical distances.
- Type:
- y_calibration¶
Real space calibration in the y-direction in Ångstroms per pixel. Converts pixel coordinates to physical distances.
- Type:
- This class is registered as a PyTree node, making it compatible with JAX
- transformations like jit, grad, and vmap. The calibration metadata is
- preserved as auxiliary data while slice data can be efficiently processed.
- All data is immutable for functional programming patterns.
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> >>> # Create potential slices for multislice calculation >>> slices_data = jnp.zeros((10, 64, 64)) # 10 slices, 64x64 each >>> potential_slices = rh.types.create_potential_slices( ... slices=slices_data, ... slice_thickness=2.0, # 2 Å per slice ... x_calibration=0.1, # 0.1 Å per pixel in x ... y_calibration=0.1, # 0.1 Å per pixel in y ... )
- class rheedium.types.XYZData(positions: Float[Array, 'N 3'], atomic_numbers: Int[Array, 'N'], lattice: Float[Array, '3 3'] | None, stress: Float[Array, '3 3'] | None, energy: Float[Array, ''] | None, properties: list[dict[str, str | int]] | None, comment: str | None)[source]¶
Bases:
NamedTupleJAX-compatible representation of parsed XYZ file data.
This PyTree represents a complete XYZ file structure with atomic positions, optional lattice information, and metadata. It’s designed for geometry parsing, simulation preparation, and machine learning data processing.
- positions¶
Cartesian atomic positions in Ångstroms. Shape (N, 3) where N is the number of atoms.
- Type:
Float[Array,"N 3"]
- atomic_numbers¶
Atomic numbers (Z) corresponding to each atom. Shape (N,) with integer values.
- Type:
Int[Array,"N"]
- lattice¶
Lattice vectors in Ångstroms if present in the XYZ file, otherwise None. Shape (3, 3) matrix where each row is a lattice vector.
- Type:
Optional[Float[Array,"3 3"]]
- stress¶
Symmetric stress tensor if present in the metadata, otherwise None. Shape (3, 3) matrix with stress components.
- Type:
Optional[Float[Array,"3 3"]]
- energy¶
Total energy in eV if present in the metadata, otherwise None. Scalar value.
- Type:
Optional[scalar_float]
- properties¶
List of per-atom properties described in the metadata, otherwise None.
- Type:
Optional[List[Dict[str,Union[str,int]]]]
- comment¶
The raw comment line from the XYZ file header, otherwise None.
- Type:
Optional[str]
- This class is registered as a PyTree node, making it compatible with JAX
- transformations like jit, grad, and vmap. Numerical data is stored as
- JAX arrays while metadata is preserved as auxiliary data. All data is
- immutable for functional programming patterns.
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> >>> # Create XYZ data for water molecule >>> positions = jnp.array( ... [ ... [0.0, 0.0, 0.0], ... [0.76, 0.59, 0.0], ... [-0.76, 0.59, 0.0], ... ] ... ) >>> atomic_numbers = jnp.array([8, 1, 1]) # O, H, H >>> xyz_data = rh.types.create_xyz_data( ... positions=positions, ... atomic_numbers=atomic_numbers, ... comment="Water molecule", ... )
- rheedium.types.create_crystal_structure(frac_positions: Num[Array, '... 4'], cart_positions: Num[Array, '... 4'], cell_lengths: Num[Array, '3'], cell_angles: Num[Array, '3']) CrystalStructure[source]¶
Create a CrystalStructure PyTree with data validation.
- Parameters:
frac_positions (
4']) – Array of shape (n_atoms, 4) containing atomic positions in fractional coordinates.cart_positions (
4']) – Array of shape (n_atoms, 4) containing atomic positions in Cartesian coordinates.cell_lengths (
Num[Array, '3']) – Unit cell lengths [a, b, c] in Ångstroms.cell_angles (
Num[Array, '3']) – Unit cell angles [α, β, γ] in degrees.
- Returns:
validated_crystal_structure – A validated CrystalStructure instance.
- Return type:
Notes
Convert all inputs to JAX arrays using jnp.asarray.
Validate shapes of frac_positions, cart_positions, cell_lengths, and cell_angles.
Verify number of atoms matches between frac and cart positions.
Verify atomic numbers match between frac and cart positions.
Ensure cell lengths are positive.
Ensure cell angles are between 0 and 180 degrees.
Create and return CrystalStructure instance with validated data.
- rheedium.types.create_ewald_data(wavelength_ang: Float[Array, ''], k_magnitude: Float[Array, ''], sphere_radius: Float[Array, ''], recip_vectors: Float[Array, '3 3'], hkl_grid: Int[Array, 'N 3'], g_vectors: Float[Array, 'N 3'], g_magnitudes: Float[Array, 'N'], structure_factors: Complex[Array, 'N'], intensities: Float[Array, 'N']) EwaldData[source]¶
Create an EwaldData PyTree with validation.
- Parameters:
wavelength_ang (
Float[Array, '']) – Electron wavelength in Ångstroms.k_magnitude (
Float[Array, '']) – Wavevector magnitude \(|k| = 2\pi/\lambda\) in 1/Ångstroms.sphere_radius (
Float[Array, '']) – Ewald sphere radius in 1/Ångstroms.recip_vectors (
Float[Array, '3 3']) – Reciprocal lattice basis vectors as 3×3 matrix.hkl_grid (
Int[Array, 'N 3']) – Miller indices for N reciprocal lattice points.g_vectors (
Float[Array, 'N 3']) – Reciprocal lattice vectors for N points.g_magnitudes (
Float[Array, 'N']) – Magnitudes of N reciprocal vectors.structure_factors (
Complex[Array, 'N']) – Complex structure factors for N points.intensities (
Float[Array, 'N']) – Diffraction intensities for N points.
- Returns:
ewald_data – Validated EwaldData PyTree instance.
- Return type:
Notes
Convert dtypes – float64 for real-valued fields, int32 for Miller indices, complex128 for structure factors.
Validate scalars – Wavelength, k_magnitude, and sphere_radius must be positive.
Validate shapes – recip_vectors is (3, 3); hkl_grid, g_vectors, g_magnitudes, structure_factors, and intensities share the same leading dimension N.
Validate values – Intensities must be non-negative; all real-valued arrays must be finite.
Create instance – Assemble validated arrays into EwaldData PyTree.
- rheedium.types.create_kirkland_parameters(lorentzian_amplitudes: Float[Array, '3'], lorentzian_scales: Float[Array, '3'], gaussian_amplitudes: Float[Array, '3'], gaussian_scales: Float[Array, '3']) KirklandParameters[source]¶
Create a KirklandParameters PyTree with data validation.
- Parameters:
lorentzian_amplitudes (
Float[Array, '3']) – Lorentzian amplitude coefficients (a_1, a_2, a_3).lorentzian_scales (
Float[Array, '3']) – Lorentzian scale coefficients (b_1, b_2, b_3).gaussian_amplitudes (
Float[Array, '3']) – Gaussian amplitude coefficients (c_1, c_2, c_3).gaussian_scales (
Float[Array, '3']) – Gaussian scale coefficients (d_1, d_2, d_3).
- Returns:
validated_kirkland_parameters – Validated KirklandParameters instance.
- Return type:
Notes
Convert inputs to JAX float64 arrays.
Validate all arrays have exactly 3 elements.
Ensure all values are finite.
Create and return KirklandParameters instance.
- rheedium.types.create_potential_slices(slices: Float[Array, 'n_slices height width'], slice_thickness: float | Float[Array, ''], x_calibration: float | Float[Array, ''], y_calibration: float | Float[Array, '']) PotentialSlices[source]¶
Create a PotentialSlices PyTree with data validation.
- Parameters:
slices (
Float[Array, 'n_slices height width']) – 3D array containing projected-potential data in Volt-Angstrom for each slice.slice_thickness (
Union[float,Float[Array, '']]) – Thickness of each slice in Ångstroms.x_calibration (
Union[float,Float[Array, '']]) – Real space calibration in x-direction in Ångstroms per pixel.y_calibration (
Union[float,Float[Array, '']]) – Real space calibration in y-direction in Ångstroms per pixel.
- Returns:
validated_potential_slices – Validated PotentialSlices instance.
- Return type:
Notes
Convert inputs to JAX arrays with appropriate dtypes.
Validate slice array is 3D.
Ensure slice thickness is positive.
Ensure calibrations are positive.
Check that all slice data is finite.
Create and return PotentialSlices instance.
- rheedium.types.create_xyz_data(positions: Float[Array, 'N 3'], atomic_numbers: Int[Array, 'N'], lattice: Float[Array, '3 3'] | None = None, stress: Float[Array, '3 3'] | None = None, energy: float | Float[Array, ''] | None = None, properties: list[dict[str, str | int]] | None = None, comment: str | None = None) XYZData[source]¶
Create a XYZData PyTree with runtime validation.
- Parameters:
positions (
Float[Array, 'N 3']) – Cartesian positions in Ångstroms.atomic_numbers (
Int[Array, 'N']) – Atomic numbers (Z) for each atom.lattice (
Optional[Float[Array, '3 3']], default:None) – Lattice vectors (if any).stress (
Optional[Float[Array, '3 3']], default:None) – Stress tensor (if any).energy (
Union[float,Float[Array, ''],None], default:None) – Total energy (if any).properties (
Optional[list[dict[str,Union[str,int]]]], default:None) – Per-atom metadata.comment (
Optional[str], default:None) – Original XYZ comment line.
- Returns:
validated_xyz_data – Validated PyTree structure for XYZ file contents.
- Return type:
Notes
Convert required inputs to JAX arrays with appropriate dtypes: positions to float64, atomic_numbers to int32, lattice/stress/energy to float64 if provided.
Execute shape validation checks: verify positions has shape (N, 3) and atomic_numbers has shape (N,).
Execute value validation checks: ensure all position values are finite and atomic numbers are non-negative.
Execute optional matrix validation checks: for lattice and stress tensors verify shape is (3, 3) and all values are finite.
If all validations pass, create and return XYZData instance.
If any validation fails, raise ValueError with descriptive error message.
- rheedium.types.float_jax_image¶
alias of
Float[Array, 'H W']
- rheedium.types.float_np_image¶
alias of
Float[ndarray, 'H W']
- rheedium.types.int_jax_image¶
alias of
Integer[Array, 'H W']
- rheedium.types.int_np_image¶
alias of
Integer[ndarray, 'H W']
- class rheedium.types.OrientationDistribution(discrete_angles_deg: Float[Array, 'M'], discrete_weights: Float[Array, 'M'], mosaic_fwhm_deg: Float[Array, ''], distribution_id: str | None = None)[source]¶
Bases:
NamedTupleProbability distribution over domain azimuthal orientations.
Extended Summary¶
Models the statistical distribution of in-plane domain rotations on the illuminated surface. Supports discrete variants (e.g., rotational twins), continuous mosaic spread, or combinations.
The total intensity is computed as an incoherent sum:
\[\begin{split}I(G) = \\int P(\\theta) \\, |F(G, \\theta)|^2 \\, d\\theta\end{split}\]For discrete variants this becomes:
\[\begin{split}I(G) = \\sum_i w_i \\, |F(G, \\theta_i)|^2\end{split}\]- discrete_angles_deg¶
Azimuthal rotation angles for discrete variants in degrees. For continuous-only distributions, use a single-element array with the center angle.
- Type:
Float[Array,"M"]
- discrete_weights¶
Probability weights for each discrete angle. Normalized internally to sum to 1.0. Must be non-negative.
- Type:
Float[Array,"M"]
- mosaic_fwhm_deg¶
Full-width at half-maximum of Gaussian mosaic spread around each discrete angle, in degrees. Set to 0.0 for sharp discrete variants with no mosaic broadening.
- Type:
Float[Array,""]
- distribution_id¶
Optional identifier for the distribution (e.g., “sqrt13_R33.7”).
- Type:
Optional[str]
Notes
The distribution is parameterized to handle three common cases:
Discrete variants only (mosaic_fwhm_deg = 0): Sharp peaks at specified angles. Example: √13×√13 R±33.7° reconstruction with two domains.
Continuous mosaic only (single angle, mosaic_fwhm_deg > 0): Gaussian spread around a central orientation. Models strain relaxation or polycrystalline texture.
Mixed (multiple angles, mosaic_fwhm_deg > 0): Each discrete variant is broadened by the mosaic spread. Most realistic for real surfaces.
Examples
>>> # Two rotational variants at ±33.7° >>> dist = OrientationDistribution( ... discrete_angles_deg=jnp.array([33.7, -33.7]), ... discrete_weights=jnp.array([0.5, 0.5]), ... mosaic_fwhm_deg=jnp.array(0.0), ... )
>>> # Gaussian mosaic spread of 0.5° FWHM >>> dist = OrientationDistribution( ... discrete_angles_deg=jnp.array([0.0]), ... discrete_weights=jnp.array([1.0]), ... mosaic_fwhm_deg=jnp.array(0.5), ... )
- discrete_angles_deg: Float[Array, 'M']¶
Alias for field number 0
- discrete_weights: Float[Array, 'M']¶
Alias for field number 1
- mosaic_fwhm_deg: Float[Array, '']¶
Alias for field number 2
- class rheedium.types.SizeDistribution(distribution_type: str, mean_ang: Float[Array, ''], sigma_ang: Float[Array, ''], min_size_ang: Float[Array, ''], max_size_ang: Float[Array, ''])[source]¶
Bases:
NamedTupleProbability distribution over coherent domain sizes.
Extended Summary¶
Models the statistical distribution of lateral coherent domain sizes on the illuminated surface. Domain size determines rod broadening via σ_rod = 2π / (L × √(2π)).
- distribution_type¶
Type of distribution: “lognormal”, “gaussian”, “exponential”, “delta”. Lognormal is most physical for nucleation/coalescence.
- Type:
- mean_ang¶
Mean domain size in Ångstroms.
- Type:
Float[Array,""]
- sigma_ang¶
Standard deviation in Ångstroms. For lognormal, this is the underlying normal distribution’s σ.
- Type:
Float[Array,""]
- min_size_ang¶
Minimum size cutoff in Ångstroms. Avoids unphysical small domains. Typical: 5-20 Å.
- Type:
Float[Array,""]
- max_size_ang¶
Maximum size cutoff in Ångstroms. Computational truncation. Typical: 500-2000 Å.
- Type:
Float[Array,""]
Notes
The distribution affects RHEED patterns through rod broadening: smaller domains → broader rods → more diffuse streaks.
For “delta” distribution, all domains have exactly mean_ang size.
- mean_ang: Float[Array, '']¶
Alias for field number 1
- sigma_ang: Float[Array, '']¶
Alias for field number 2
- min_size_ang: Float[Array, '']¶
Alias for field number 3
- max_size_ang: Float[Array, '']¶
Alias for field number 4
- rheedium.types.create_discrete_orientation(angles_deg: Float[Array, 'M'], weights: Float[Array, 'M'] | None = None, distribution_id: str | None = None) OrientationDistribution[source]¶
Create discrete orientation distribution for rotational variants.
- Parameters:
- Returns:
dist – Discrete orientation distribution with no mosaic spread.
- Return type:
Examples
>>> # √13×√13 R±33.7° reconstruction >>> dist = create_discrete_orientation( ... angles_deg=jnp.array([33.7, -33.7]), ... weights=jnp.array([0.5, 0.5]), ... distribution_id="sqrt13_R33.7", ... )
>>> # 4-fold symmetric variants >>> dist = create_discrete_orientation( ... angles_deg=jnp.array([0.0, 90.0, 180.0, 270.0]), ... )
- rheedium.types.create_gaussian_orientation(center_deg: float | Float[Array, ''] = 0.0, fwhm_deg: float | Float[Array, ''] = 0.5, distribution_id: str | None = None) OrientationDistribution[source]¶
Create Gaussian mosaic spread orientation distribution.
- Parameters:
center_deg (
Union[float,Float[Array, '']], default:0.0) – Center of the distribution in degrees. Default: 0.0fwhm_deg (
Union[float,Float[Array, '']], default:0.5) – Full-width at half-maximum in degrees. Default: 0.5distribution_id (
Optional[str], default:None) – Identifier for the distribution.
- Returns:
dist – Continuous Gaussian orientation distribution.
- Return type:
Notes
FWHM relates to Gaussian σ by: FWHM = 2√(2 ln 2) × σ ≈ 2.355 σ
- rheedium.types.create_lognormal_size(mean_ang: float | Float[Array, ''] = 100.0, sigma_ang: float | Float[Array, ''] = 30.0, min_size_ang: float | Float[Array, ''] = 10.0, max_size_ang: float | Float[Array, ''] = 500.0) SizeDistribution[source]¶
Create lognormal domain size distribution.
- Parameters:
mean_ang (
Union[float,Float[Array, '']], default:100.0) – Mean domain size in Ångstroms. Default: 100.0sigma_ang (
Union[float,Float[Array, '']], default:30.0) – Standard deviation in Ångstroms. Default: 30.0min_size_ang (
Union[float,Float[Array, '']], default:10.0) – Minimum size cutoff. Default: 10.0 Åmax_size_ang (
Union[float,Float[Array, '']], default:500.0) – Maximum size cutoff. Default: 500.0 Å
- Returns:
dist – Lognormal size distribution.
- Return type:
Notes
Lognormal is most physical for domain sizes arising from nucleation and coalescence processes. The mode (peak) of the distribution is at exp(μ - σ²) where μ, σ are the underlying normal parameters.
- rheedium.types.create_mixed_orientation(angles_deg: Float[Array, 'M'], weights: Float[Array, 'M'] | None = None, mosaic_fwhm_deg: float | Float[Array, ''] = 0.2, distribution_id: str | None = None) OrientationDistribution[source]¶
Create mixed distribution with discrete variants and mosaic spread.
- Parameters:
angles_deg (
Float[Array, 'M']) – Rotation angles for discrete variants in degrees.weights (
Optional[Float[Array, 'M']], default:None) – Probability weights for variants. Default: equal weights.mosaic_fwhm_deg (
Union[float,Float[Array, '']], default:0.2) – Mosaic FWHM around each variant in degrees. Default: 0.2distribution_id (
Optional[str], default:None) – Identifier for the distribution.
- Returns:
dist – Mixed discrete + continuous orientation distribution.
- Return type:
Notes
Each discrete variant peak is broadened by a Gaussian with the specified FWHM. This is the most realistic model for real surfaces.
- rheedium.types.create_orientation_distribution(angles_deg: Float[Array, 'M'], weights: Float[Array, 'M'] | None = None, mosaic_fwhm_deg: float | Float[Array, ''] = 0.0, distribution_id: str | None = None) OrientationDistribution[source]¶
Create an OrientationDistribution with normalized JAX arrays.
- Parameters:
angles_deg (
Float[Array, 'M']) – Rotation angles for each supported orientation in degrees.weights (
Optional[Float[Array, 'M']], default:None) – Probability weights for each angle. Default: equal weights.mosaic_fwhm_deg (
Union[float,Float[Array, '']], default:0.0) – Gaussian mosaic broadening FWHM in degrees. Negative values are clamped to 0.0. Default: 0.0distribution_id (
Optional[str], default:None) – Identifier for the distribution.
- Returns:
dist – Orientation distribution with normalized weights and a non-negative mosaic width.
- Return type:
- rheedium.types.discretize_orientation(dist: OrientationDistribution, n_mosaic_points: int | Integer[Array, ''] = 7, n_sigma_range: float | Float[Array, ''] = 3.0) tuple[Float[Array, 'N'], Float[Array, 'N']][source]¶
Convert OrientationDistribution to quadrature points and weights.
Description¶
Discretizes the orientation probability distribution into a set of angle samples and corresponding integration weights. Uses Gauss-Hermite quadrature around each discrete peak, with the spread controlled by mosaic_fwhm_deg.
- param dist:
Orientation probability distribution.
- type dist:
- param n_mosaic_points:
Number of Gauss-Hermite quadrature points per discrete peak for mosaic integration. Default: 7
- type n_mosaic_points:
Union[int,Integer[Array, '']], default:7- param n_sigma_range:
Number of sigma to extend mosaic sampling. Default: 3.0
- type n_sigma_range:
Union[float,Float[Array, '']], default:3.0- rtype:
tuple[Float[Array, 'N'],Float[Array, 'N']]- returns:
angles_deg (
Float[Array,"N"]) – Quadrature angle samples in degrees. Shape: M × n_mosaic_pointsweights (
Float[Array,"N"]) – Integration weights (sum to 1.0).
Notes
When mosaic_fwhm_deg is very small (< 1e-6), the quadrature points collapse onto the discrete peaks, exactly reproducing delta-function behavior in the numerical quadrature.
The total number of output points is always M × n_mosaic_points.
- rheedium.types.discretize_orientation_static(dist: OrientationDistribution, n_mosaic_points: int | Integer[Array, ''] = 7) tuple[Float[Array, 'N'], Float[Array, 'N']][source]¶
Static-dispatch version for use outside JIT when efficiency matters.
Description¶
When the distribution type is known at Python level (not traced), this version uses Python branching for efficiency: discrete-only distributions return M points instead of M × n_mosaic_points.
- param dist:
Orientation probability distribution.
- type dist:
- param n_mosaic_points:
Quadrature points per peak for mosaic. Default: 7
- type n_mosaic_points:
Union[int,Integer[Array, '']], default:7- rtype:
tuple[Float[Array, 'N'],Float[Array, 'N']]- returns:
angles_deg (
Float[Array,"N"]) – Quadrature angle samples in degrees.weights (
Float[Array,"N"]) – Integration weights (sum to 1.0).
Notes
Use this version when calling outside of JIT for efficiency. Use discretize_orientation inside JIT-compiled functions.
- rheedium.types.integrate_over_orientation(simulate_fn: Callable[[float | Float[Array, '']], Float[Array, 'H W']], orientation_dist: OrientationDistribution, n_mosaic_points: int | Integer[Array, ''] = 7) Float[Array, 'H W'][source]¶
Compute incoherent intensity sum over orientation distribution.
Description¶
Integrates RHEED intensity over the orientation probability distribution using numerical quadrature. Each orientation sample is simulated independently, then intensities are summed with distribution weights.
This implements the statistical ensemble averaging:
\[\begin{split}I_{total}(G) = \\int P(\\theta) \\, I(G, \\theta) \\, d\\theta \\approx \\sum_i w_i \\, I(G, \\theta_i)\end{split}\]- param simulate_fn:
Function mapping azimuthal angle (degrees) to RHEED intensity pattern. Must be vmappable. Signature: phi_deg → pattern.
- type simulate_fn:
Callable[[Union[float,Float[Array, '']]],Float[Array, 'H W']]- param orientation_dist:
Probability distribution over orientations.
- type orientation_dist:
- param n_mosaic_points:
Quadrature points for mosaic spread. Default: 7
- type n_mosaic_points:
Union[int,Integer[Array, '']], default:7- returns:
averaged_pattern – Incoherently averaged RHEED intensity pattern.
- rtype:
Float[Array, 'H W']
Notes
The simulate_fn should capture all other parameters (crystal structure, beam energy, incidence angle, etc.) via closure. Only the azimuthal angle varies during integration.
For pure discrete distributions (no mosaic), this reduces to a weighted sum over the discrete variants.
Examples
>>> # Define simulation function (captures other params) >>> def sim_at_phi(phi_deg): ... return simulate_rheed(crystal, theta=2.0, phi=phi_deg, ...) >>> >>> # Create distribution >>> dist = create_discrete_orientation(jnp.array([33.7, -33.7])) >>> >>> # Integrate >>> pattern = integrate_over_orientation(sim_at_phi, dist)
- class rheedium.types.DetectorGeometry(distance: float = 100.0, tilt_angle: float = 0.0, curvature_radius: float = inf, center_offset_h: float = 0.0, center_offset_v: float = 0.0, psf_sigma_pixels: float = 1.0)[source]¶
Bases:
NamedTupleConfiguration for RHEED detector geometry.
This NamedTuple specifies the geometry of the detector screen for accurate projection of diffracted beams. Supports flat, tilted, and curved detector screens.
- tilt_angle¶
Tilt angle of the detector about the horizontal axis in degrees. Positive tilt rotates the top of the screen away from the sample. Default: 0.0 (vertical screen)
- Type:
- curvature_radius¶
Radius of curvature of the detector screen in mm. Use jnp.inf for flat screen. Default: jnp.inf (flat)
- Type:
- center_offset_h¶
Horizontal offset of detector center from beam axis in mm. Positive values shift the detector right. Default: 0.0
- Type:
- center_offset_v¶
Vertical offset of detector center from beam axis in mm. Positive values shift the detector up. Default: 0.0
- Type:
- psf_sigma_pixels¶
Point spread function 1-sigma width in pixels. Models phosphor grain size, camera lens blur, and CCD pixel diffusion. Typical: 0.5–2.0 pixels. Use 0.0 to disable PSF convolution. Default: 1.0
- Type:
Notes
For a standard RHEED setup: - The beam travels predominantly along +x (into the sample surface) - The detector is placed in the yz-plane at x = distance - Horizontal corresponds to y-direction, vertical to z-direction
The tilt angle accounts for common experimental setups where the phosphor screen is not perfectly perpendicular to the nominal beam direction.
For curved screens (e.g., cylindrical CCD detector arrays), the curvature_radius determines the cylinder radius. Points on the detector surface lie on this cylinder.
- class rheedium.types.RHEEDImage(img_array: Float[Array, 'H W'], incoming_angle: float | Float[Array, ''], calibration: Float[Array, '2'] | float | Float[Array, ''], electron_wavelength: float | Float[Array, ''], detector_distance: int | float | Num[Array, ''])[source]¶
Bases:
NamedTupleJAX-compatible experimental RHEED image data structure.
This PyTree represents an experimental RHEED image with associated experimental parameters including beam geometry, detector calibration, and electron beam properties for quantitative RHEED analysis.
- img_array¶
2D image array with shape (height, width) containing pixel intensity values. Non-negative finite values.
- Type:
- incoming_angle¶
Angle of the incoming electron beam in degrees, typically between 0 and 90 degrees for grazing incidence geometry.
- Type:
- calibration¶
Calibration factor for converting pixels to physical units. Either a scalar (same calibration for both axes) or array of shape (2,) with separate [x, y] calibrations in appropriate units per pixel.
- Type:
Union[Float[Array,"2"],scalar_float]
- electron_wavelength¶
Wavelength of the electrons in Ångstroms. Determines the diffraction geometry and resolution.
- Type:
- detector_distance¶
Distance from the sample to the detector in mm. Affects the angular resolution and reciprocal space mapping.
- Type:
Notes
This class is registered as a PyTree node, making it compatible with JAX transformations like jit, grad, and vmap. All data is immutable for functional programming patterns and efficient image processing.
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> >>> # Create RHEED image with experimental parameters >>> image = jnp.ones((256, 512)) # 256x512 pixel RHEED image >>> rheed_img = rh.types.create_rheed_image( ... img_array=image, ... incoming_angle=2.0, # 2 degree grazing angle ... calibration=0.01, # 0.01 units per pixel ... electron_wavelength=0.037, # 10 keV electrons ... detector_distance=1000.0, # 1000 Å to detector ... )
- class rheedium.types.RHEEDPattern(G_indices: Int[Array, 'N'], k_out: Float[Array, 'M 3'], detector_points: Float[Array, 'M 2'], intensities: Float[Array, 'M'])[source]¶
Bases:
NamedTupleJAX-compatible RHEED diffraction pattern data structure.
This PyTree represents a RHEED diffraction pattern containing reflection data including reciprocal lattice indices, outgoing wavevectors, detector coordinates, and intensity values for electron diffraction analysis.
- G_indices¶
Indices of reciprocal-lattice vectors that satisfy reflection conditions. Variable length array of integer indices.
- Type:
Int[Array,"N"]
- k_out¶
Outgoing wavevectors in 1/Å for reflections. Shape (M, 3) where M is the number of reflections and each row contains [kx, ky, kz] components.
- Type:
Float[Array,"M 3"]
- detector_points¶
Detector coordinates (Y, Z) on the detector plane in mm. Shape (M, 2) where each row contains [y, z] coordinates.
- Type:
Float[Array,"M 2"]
- intensities¶
Intensity values for each reflection. Shape (M,) with non-negative intensity values.
- Type:
Float[Array,"M"]
- This class is registered as a PyTree node, making it compatible with JAX
- transformations like jit, grad, and vmap. All data is immutable and
- stored in JAX arrays for efficient RHEED pattern analysis.
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> >>> # Create RHEED pattern data >>> G_indices = jnp.array([1, 2, 3]) >>> k_out = jnp.array([[1.0, 0.0, 0.5], [2.0, 0.0, 1.0], [3.0, 0.0, 1.5]]) >>> detector_points = jnp.array([[10.0, 5.0], [20.0, 10.0], [30.0, 15.0]]) >>> intensities = jnp.array([100.0, 80.0, 60.0]) >>> pattern = rh.types.create_rheed_pattern( ... G_indices=G_indices, ... k_out=k_out, ... detector_points=detector_points, ... intensities=intensities, ... )
- class rheedium.types.SlicedCrystal(cart_positions: Float[Array, 'N 4'], cell_lengths: Float[Array, '3'], cell_angles: Float[Array, '3'], orientation: Int[Array, '3'], depth: float | Float[Array, ''], x_extent: float | Float[Array, ''], y_extent: float | Float[Array, ''])[source]¶
Bases:
NamedTupleJAX-compatible surface-oriented crystal structure for RHEED simulation.
This PyTree represents a crystal structure that has been sliced and oriented for RHEED simulations. The structure contains atoms from a surface region extended in x and y directions to cover a large area (>100 Å typically), with a specified depth perpendicular to the surface.
- cart_positions¶
Cartesian coordinates of atoms in the slab with atomic numbers. Shape (N, 4) where each row is [x, y, z, atomic_number]. Coordinates are in Ångstroms.
- Type:
Float[Array,"N 4"]
- cell_lengths¶
Lengths of the supercell edges [a, b, c] in Ångstroms. These define the periodicity of the extended surface slab.
- Type:
Float[Array,"3"]
- cell_angles¶
Angles between supercell edges [alpha, beta, gamma] in degrees. Typically [90, 90, 90] for surface slabs.
- Type:
Float[Array,"3"]
- orientation¶
Miller indices [h, k, l] of the surface orientation. Example: [1, 1, 1] for a (111) surface, [0, 0, 1] for (001).
- Type:
Int[Array,"3"]
- depth¶
Depth of the slab perpendicular to the surface in Ångstroms. Atoms within this depth from the surface are included.
- Type:
- x_extent¶
Lateral extent of the slab in the x-direction in Ångstroms. Should be >100 Å for realistic RHEED simulation.
- Type:
- y_extent¶
Lateral extent of the slab in the y-direction in Ångstroms. Should be >100 Å for realistic RHEED simulation.
- Type:
Notes
This class is registered as a PyTree node, making it compatible with JAX transformations. The structure is designed specifically for RHEED simulations where: - The z-direction is perpendicular to the surface (beam grazing angle) - The x-y plane is the surface plane - Large lateral extents (x_extent, y_extent) ensure realistic coherence - Limited depth models the surface sensitivity of RHEED
Examples
>>> import jax.numpy as jnp >>> import rheedium as rh >>> >>> # Create a (111) surface slab >>> cart_positions = jnp.array( ... [ ... [0.0, 0.0, 0.0, 14.0], # Si atom ... [1.0, 1.0, 0.5, 14.0], ... ] ... ) # Another Si >>> sliced = rh.types.create_sliced_crystal( ... cart_positions=cart_positions, ... cell_lengths=jnp.array([150.0, 150.0, 20.0]), ... cell_angles=jnp.array([90.0, 90.0, 90.0]), ... orientation=jnp.array([1, 1, 1]), ... depth=20.0, ... x_extent=150.0, ... y_extent=150.0, ... )
- class rheedium.types.SurfaceConfig(method: str = 'height', height_fraction: float = 0.3, coordination_cutoff: float = 3.0, coordination_threshold: int = 8, n_layers: int = 1, layer_tolerance: float = 0.5, explicit_mask: Bool[Array, 'N'] | None = None)[source]¶
Bases:
NamedTupleConfiguration for surface atom identification.
This NamedTuple specifies how to identify which atoms are considered surface atoms for enhanced Debye-Waller factors in RHEED simulations.
- method¶
Surface identification method: - “height”: top fraction by z-coordinate (default) - “coordination”: atoms with fewer neighbors than bulk - “layers”: atoms in topmost N complete layers - “explicit”: user-provided surface mask
- Type:
- height_fraction¶
For “height” method: fraction of z-range considered surface. Default: 0.3 (top 30% of atoms by height)
- Type:
- coordination_cutoff¶
For “coordination” method: cutoff distance in Angstroms for counting neighbors. Default: 3.0
- Type:
- coordination_threshold¶
For “coordination” method: atoms with fewer than this many neighbors are considered surface. Default: 8 (typical for FCC)
- Type:
- layer_tolerance¶
For “layers” method: tolerance for grouping atoms into layers in Angstroms. Default: 0.5
- Type:
- explicit_mask¶
For “explicit” method: user-provided boolean mask. Must have same length as number of atoms. Default: None
- Type:
Bool[Array,"N"] | None
- rheedium.types.create_rheed_image(img_array: Float[Array, 'H W'], incoming_angle: float | Float[Array, ''], calibration: Float[Array, '2'] | float | Float[Array, ''], electron_wavelength: float | Float[Array, ''], detector_distance: int | float | Num[Array, '']) RHEEDImage[source]¶
Create a RHEEDImage instance with data validation.
- Parameters:
img_array (
Float[Array, 'H W']) – The image in 2D array format.incoming_angle (
Union[float,Float[Array, '']]) – The angle of the incoming electron beam in degrees.calibration (
Union[Float[Array, '2'],float,Float[Array, '']]) – Calibration factor for the image, either as a 2D array or a scalar.electron_wavelength (
Union[float,Float[Array, '']]) – The wavelength of the electrons in Ångstroms.detector_distance (
Union[int,float,Num[Array, '']]) – The distance from the sample to the detector in mm.
- Returns:
validated_rheed_image – Validated RHEED image instance.
- Return type:
Notes
Convert inputs to JAX arrays.
Validate image array: check it is 2D, all values are finite and non-negative.
Validate parameters: check incoming_angle is between 0 and 90 degrees, electron_wavelength is positive, and detector_distance is positive.
Validate calibration: if scalar, ensure it is positive; if array, ensure shape is (2,) and all values are positive.
Create and return RHEEDImage instance.
- rheedium.types.create_rheed_pattern(g_indices: Int[Array, 'N'], k_out: Float[Array, 'M 3'], detector_points: Float[Array, 'M 2'], intensities: Float[Array, 'M']) RHEEDPattern[source]¶
Create a RHEEDPattern instance with data validation.
- Parameters:
g_indices (
Int[Array, 'N']) – Indices of reciprocal-lattice vectors that satisfy reflection.k_out (
Float[Array, 'M 3']) – Outgoing wavevectors (in 1/Å) for those reflections.detector_points (
Float[Array, 'M 2']) – (Y, Z) coordinates on the detector plane, in mm.intensities (
Float[Array, 'M']) – Intensities for each reflection.
- Returns:
validated_rheed_pattern – Validated RHEED pattern instance.
- Return type:
Notes
Convert inputs to JAX arrays.
Validate array shapes: check k_out has shape (M, 3), detector_points has shape (M, 2), intensities has shape (M,), and g_indices has length M.
Validate data: ensure intensities are non-negative, k_out vectors are non-zero, and detector points are finite.
Create and return RHEEDPattern instance.
- rheedium.types.create_sliced_crystal(cart_positions: Float[Array, 'N 4'], cell_lengths: Float[Array, '3'], cell_angles: Float[Array, '3'], orientation: Int[Array, '3'], depth: float | Float[Array, ''], x_extent: float | Float[Array, ''], y_extent: float | Float[Array, '']) SlicedCrystal[source]¶
Create a SlicedCrystal instance with data validation.
- Parameters:
cart_positions (
Float[Array, 'N 4']) – Cartesian atomic positions with atomic numbers [x, y, z, Z].cell_lengths (
Float[Array, '3']) – Supercell edge lengths [a, b, c] in Ångstroms.cell_angles (
Float[Array, '3']) – Supercell angles [alpha, beta, gamma] in degrees.orientation (
Int[Array, '3']) – Miller indices [h, k, l] of surface orientation.depth (
Union[float,Float[Array, '']]) – Slab depth perpendicular to surface in Ångstroms.x_extent (
Union[float,Float[Array, '']]) – Lateral extent in x-direction in Ångstroms.y_extent (
Union[float,Float[Array, '']]) – Lateral extent in y-direction in Ångstroms.
- Returns:
validated_sliced_crystal – Validated SlicedCrystal instance.
- Return type:
Notes
Verify cart_positions shape is (N, 4) with N > 0.
Verify cell_lengths, cell_angles, orientation have correct shapes.
Ensure all positions are finite.
Ensure depth, x_extent, y_extent are positive.
Recommend x_extent and y_extent >= 100 Angstroms.
Validate atomic numbers (cart_positions[:, 3]) are in valid range [1, 118].
- rheedium.types.identify_surface_atoms(atom_positions: Float[Array, 'N 3'], config: SurfaceConfig = _DEFAULT_SURFACE_CONFIG) Bool[Array, 'N'][source]¶
Identify surface atoms using the specified method.
- Parameters:
atom_positions (
Float[Array, 'N 3']) – Cartesian atomic positions in Angstroms, shape (N, 3).config (
SurfaceConfig, default:_DEFAULT_SURFACE_CONFIG) – Surface identification configuration. Default: SurfaceConfig() with height-based method at 30% fraction.
- Returns:
is_surface – Boolean mask indicating which atoms are surface atoms.
- Return type:
Bool[Array, 'N']
Notes
Available methods:
height: Uses z-coordinate threshold. Atoms in the top height_fraction of the z-range are marked as surface.
coordination: Uses neighbor counting. Atoms with fewer than coordination_threshold neighbors within coordination_cutoff distance are marked as surface. This is more physical for reconstructed or stepped surfaces.
layers: Identifies discrete atomic layers by z-coordinate and marks the topmost n_layers as surface. Uses layer_tolerance to group atoms into layers.
explicit: Uses user-provided mask directly from config.explicit_mask.
Examples
>>> import jax.numpy as jnp >>> from rheedium.types import SurfaceConfig, identify_surface_atoms >>> positions = jnp.array([[0, 0, 0], [0, 0, 1], [0, 0, 2]]) >>> # Height-based (default) >>> mask = identify_surface_atoms(positions) >>> # Coordination-based >>> config = SurfaceConfig(method="coordination", coordination_cutoff=2.5) >>> mask = identify_surface_atoms(positions, config)