API reference

The symbols below are re-exported from the top-level ebsdsim package.

Simulation

Public API for EBSD master-pattern generation.

class ebsdsim.api.Atom(element, x, y, z, occupancy=1.0, b_iso=None)[source]

Bases: object

Crystallographic site in fractional coordinates (direct lattice).

Parameters:
  • element (str) – Chemical symbol (e.g. "Ni", "Ga").

  • x (float) – Fractional coordinates in the direct unit cell.

  • y (float) – Fractional coordinates in the direct unit cell.

  • z (float) – Fractional coordinates in the direct unit cell.

  • occupancy (float, optional) – Site occupancy in [0, 1]. Default 1.0.

  • b_iso (float or None, optional) – Isotropic Debye–Waller factor in Ų. When None, a room-temperature default is used during structure-factor evaluation.

element: str
x: float
y: float
z: float
occupancy: float = 1.0
b_iso: float | None = None
__init__(element, x, y, z, occupancy=1.0, b_iso=None)
Parameters:
Return type:

None

class ebsdsim.api.Cell(a, b, c, alpha=90.0, beta=90.0, gamma=90.0, space_group=1)[source]

Bases: object

Unit-cell lattice parameters (Å and degrees).

Parameters:
  • a (float) – Lattice lengths in ångströms.

  • b (float) – Lattice lengths in ångströms.

  • c (float) – Lattice lengths in ångströms.

  • alpha (float, optional) – Interaxial angles in degrees. Default 90.0 each.

  • beta (float, optional) – Interaxial angles in degrees. Default 90.0 each.

  • gamma (float, optional) – Interaxial angles in degrees. Default 90.0 each.

  • space_group (int or str, optional) – International Tables space-group number or Hermann–Mauguin symbol. Default 1 (triclinic P1).

a: float
b: float
c: float
alpha: float = 90.0
beta: float = 90.0
gamma: float = 90.0
space_group: int | str = 1
__init__(a, b, c, alpha=90.0, beta=90.0, gamma=90.0, space_group=1)
Parameters:
Return type:

None

class ebsdsim.api.Material(cell, atoms, name='')[source]

Bases: object

Crystal specification for master-pattern simulation.

Parameters:
  • cell (Cell) – Unit-cell geometry and space group.

  • atoms (list of Atom) – Atomic sites in fractional coordinates.

  • name (str, optional) – Human-readable label stored in output metadata. Default "".

cell: Cell
atoms: list[Atom]
name: str = ''
to_simulation_cell()[source]

Build the internal simulation cell used by the GPU pipeline.

Returns:

Crystallographic cell with resolved point-group number and symmetry-expanded sites.

Return type:

Cell

__init__(cell, atoms, name='')
Parameters:
Return type:

None

class ebsdsim.api.MasterPattern(pattern, integrated, n_k, n_sites, metadata=<factory>, bin_patterns=<factory>, bin_voltages_kv=<factory>, bin_weights=<factory>, kij=None, khat=None, pg_num=None, data=<factory>, axes=<factory>)[source]

Bases: object

Rasterized master pattern and integration metadata.

pattern is the north-hemisphere Lambert raster (side, side) with side = 1 + 2 * halfw, equal to data[energy_int, site_int, 0]. It holds raw dynamical intensities; use lambert_data() for display scaling.

data is the dense Lambert tensor (E, S, H, side, side) of raw intensities. integrated and bin_patterns store fundamental-sector values (flattened (n_k * n_sites,)). kij and khat give fundamental-sector pixel indices and unit directions.

Parameters:
  • pattern (NDArray[float32])

  • integrated (NDArray[float32])

  • n_k (int)

  • n_sites (int)

  • metadata (dict[str, Any])

  • bin_patterns (list[NDArray[float32]])

  • bin_voltages_kv (list[float])

  • bin_weights (list[float])

  • kij (NDArray[int32] | None)

  • khat (NDArray[float32] | None)

  • pg_num (int | None)

  • data (NDArray[float32])

  • axes (dict[str, Any])

pattern: NDArray[float32]
integrated: NDArray[float32]
n_k: int
n_sites: int
metadata: dict[str, Any]
bin_patterns: list[NDArray[float32]]
bin_voltages_kv: list[float]
bin_weights: list[float]
kij: NDArray[int32] | None = None
khat: NDArray[float32] | None = None
pg_num: int | None = None
data: NDArray[float32]
axes: dict[str, Any]
save(path)[source]

Write this master pattern (with intermediates) to a compressed .npz.

See ebsdsim.save_master_pattern() for the on-disk format.

Parameters:

path (str | Path)

Return type:

Path

lambert_data(*, normalize=None, robust_p_low=0.01, robust_p_high=0.99)[source]

Expand raw FS intensities to Lambert (E, S, H, side, side).

Parameters:
  • normalize ({"minmax", "robust"} or None, optional) – Display scaling mode. None returns raw intensities unchanged.

  • robust_p_low (float, optional) – Percentile window used when normalize="robust".

  • robust_p_high (float, optional) – Percentile window used when normalize="robust".

Returns:

  • data (ndarray of float32) – Lambert tensor; see data for axis semantics.

  • axes (dict) – Index maps for energy, site, and hemisphere axes.

Return type:

tuple[NDArray[np.float32], dict[str, Any]]

__init__(pattern, integrated, n_k, n_sites, metadata=<factory>, bin_patterns=<factory>, bin_voltages_kv=<factory>, bin_weights=<factory>, kij=None, khat=None, pg_num=None, data=<factory>, axes=<factory>)
Parameters:
  • pattern (NDArray[float32])

  • integrated (NDArray[float32])

  • n_k (int)

  • n_sites (int)

  • metadata (dict[str, Any])

  • bin_patterns (list[NDArray[float32]])

  • bin_voltages_kv (list[float])

  • bin_weights (list[float])

  • kij (NDArray[int32] | None)

  • khat (NDArray[float32] | None)

  • pg_num (int | None)

  • data (NDArray[float32])

  • axes (dict[str, Any])

Return type:

None

ebsdsim.api.master_pattern(material, *, voltage_kv=20.0, halfw=250, dmin=0.05, energy_binwidth_keV=1.0, n_trajectories=1048576, sigma_deg=70.0, omega_deg=0.0, rank=20, exact_slow_cpu=False, verbosity=0, chunk_size=256, marginal_coverage=1.0, relative_image_stop=0.01, mc_backend='surrogate', bethe_c_strong=20.0, bethe_c_weak=40.0, bethe_c_cutoff=200.0, dbdiff_sg_cutoff=1.0, mc_auto_stop=True, mc_relative_tol=0.01, mc_min_trajectories=1048576, mc_max_trajectories=16777216)[source]
Parameters:
Return type:

MasterPattern

ebsdsim.api.master_pattern_from_cif(path, *, voltage_kv=20.0, halfw=250, dmin=0.05, energy_binwidth_keV=1.0, n_trajectories=1048576, sigma_deg=70.0, omega_deg=0.0, rank=20, exact_slow_cpu=False, verbosity=0, chunk_size=256, marginal_coverage=1.0, relative_image_stop=0.01, mc_backend='surrogate', bethe_c_strong=20.0, bethe_c_weak=40.0, bethe_c_cutoff=200.0, dbdiff_sg_cutoff=1.0, mc_auto_stop=True, mc_relative_tol=0.01, mc_min_trajectories=1048576, mc_max_trajectories=16777216)[source]
Parameters:
Return type:

MasterPattern

On-disk format

Compressed .npz export of ebsdsim master patterns.

The on-disk format stores the fundamental-sector intensities only (the minimal, symmetry-reduced representation), always keeps the per-energy-bin intermediates, and is always compressed. The embedded point-group operators and fundamental-sector normals make the file self-describing: it can be expanded back into full Lambert hemispheres with NumPy alone (see ebsdsim.mploader), without installing ebsdsim.

Arrays written

fundamental_sectorfloat32 (n_energy, n_site, n_k)

The symmetry-reduced intensities for every direction, packed along an energy axis and a site axis (raw, un-normalized). The energy axis is 1 + n_bins long when n_bins > 1 (index 0 is the energy-integrated weighted sum, index 1 + b is bin b) and length 1 otherwise. The site axis is 1 + n_sites long when n_sites > 1 (index 0 is the site mean, index 1 + s is site s) and length 1 otherwise. The north/south hemisphere of each of the n_k directions is carried by the sign column of fundamental_kij (the per-group N/S split is irregular, so hemisphere is not a separate array axis).

fundamental_kijint32 (n_k, 3)

Lambert pixel indices (i, j, sign) for each fundamental-sector direction (sign > 0 north, sign < 0 south).

fundamental_khatfloat32 (n_k, 3)

Unit propagation directions for each fundamental-sector pixel.

pg_operatorsfloat64 (n_ops, 3, 3)

Proper/improper point-group rotation matrices.

fs_normalsfloat64 (n_normals, 3)

Inward normals bounding the fundamental sector.

bin_voltages_kv / bin_weightsfloat32 (n_bins,)

Dynamical voltage (kV) and energy weight of each saved bin.

site_weightsfloat32 (n_sites,)

Normalized occupancy × multiplicity weights used for the site-integrated marginal (index 0 on the site axis). Per-site slices are raw intensities.

meta_jsonuint8 (n_bytes,)

UTF-8 JSON metadata blob (decode with bytes(arr).decode("utf-8")).

ebsdsim.save.cell_metadata(cell)[source]

Serialize a Cell to a JSON-friendly dict.

Per-site isotropic Debye–Waller factors are recorded in both Ų and nm² because they are commonly estimated and materially affect the pattern.

Parameters:

cell (Cell)

Return type:

dict[str, Any]

ebsdsim.save.save_master_pattern(mp, path)[source]

Write a master pattern (with intermediates) to a compressed .npz.

The file stores symmetry-reduced fundamental-sector intensities plus embedded point-group operators so it can be expanded offline with ebsdsim.mploader.

Parameters:
Returns:

Resolved output path.

Return type:

Path

Standalone loader

ebsdsim.mploader is intentionally NumPy-only and can be copied into other projects without the GPU stack.

Standalone, NumPy-only loader for ebsdsim master-pattern .npz files.

This module is intentionally self-contained: it depends on NumPy only and imports nothing from the rest of ebsdsim. Drop it into any project that needs to read the .npz files written by ebsdsim.save_master_pattern() and expand the symmetry-reduced fundamental sector back into full Lambert hemispheres.

Everything required for the expansion — the point-group operators and the fundamental-sector normals — is embedded in the .npz itself, so the loader needs no crystallographic tables of its own.

Quick start

>>> from ebsdsim.mploader import load_master_pattern, to_uint8, save_png_gray
>>> mp = load_master_pattern("GaN-master-pattern.npz")  # raw Lambert data in mp.data
>>> disp, _ = mp.lambert_data(normalize="robust")  # display scaling on demand
>>> nh = disp[0, 0, 0]  # energy-integrated, site-integrated, north hemisphere
>>> save_png_gray(to_uint8(nh), "GaN_integrated_nh.png")
class ebsdsim.mploader.LoadedMasterPattern(meta, integrated_fs, bin_fs, kij, khat, pg_operators, fs_normals, bin_voltages_kv, bin_weights, site_weights=None, data=<factory>, axes=<factory>, _maps=<factory>)[source]

Bases: object

Master pattern loaded from a .npz file.

meta holds simulation metadata. integrated_fs and bin_fs are fundamental-sector intensities; data is the expanded Lambert tensor of raw values. See axes for index maps.

Parameters:
  • meta (dict[str, Any])

  • integrated_fs (NDArray[float32])

  • bin_fs (NDArray[float32])

  • kij (NDArray[int32])

  • khat (NDArray[float32])

  • pg_operators (NDArray[float64])

  • fs_normals (NDArray[float64])

  • bin_voltages_kv (NDArray[float32])

  • bin_weights (NDArray[float32])

  • site_weights (NDArray[float32] | None)

  • data (NDArray[float32])

  • axes (dict[str, Any])

  • _maps (dict[bool, tuple[NDArray[float32], NDArray[float32], NDArray[uint8]]])

meta: dict[str, Any]
integrated_fs: NDArray[float32]
bin_fs: NDArray[float32]
kij: NDArray[int32]
khat: NDArray[float32]
pg_operators: NDArray[float64]
fs_normals: NDArray[float64]
bin_voltages_kv: NDArray[float32]
bin_weights: NDArray[float32]
site_weights: NDArray[float32] | None = None
data: NDArray[float32]
axes: dict[str, Any]
property halfw: int
property side: int
property n_k: int
property n_sites: int
property n_bins: int
property is_centrosymmetric: bool
property needs_southern_hemisphere: bool
reduce_over_sites(values_fs)[source]

Collapse a (n_k, n_sites) array to one value per direction.

Parameters:

values_fs (NDArray[floating])

Return type:

NDArray[float32]

lambert_data(*, normalize=None, robust_p_low=0.01, robust_p_high=0.99)[source]

Expand raw FS intensities to Lambert (E, S, H, side, side).

normalize is None (raw), "minmax", or "robust". Display scaling is applied on demand only; data always stays raw.

Parameters:
  • normalize (Literal['minmax', 'robust'] | None)

  • robust_p_low (float)

  • robust_p_high (float)

Return type:

tuple[NDArray[float32], dict[str, Any]]

reconstruct(values_fs=None, *, normalize=None, robust_p_low=0.01, robust_p_high=0.99, interp='bilinear')[source]

Expand fundamental-sector values into full (side, side) hemispheres.

Returns (nh, sh). For centrosymmetric groups sh is a copy of nh. If values_fs is None the integrated pattern is used.

Parameters:
  • values_fs (NDArray[floating] | None)

  • normalize (Literal['minmax', 'robust'] | None)

  • robust_p_low (float)

  • robust_p_high (float)

  • interp (Literal['nearest', 'bilinear'])

Return type:

tuple[NDArray[float32], NDArray[float32]]

reconstruct_integrated(**kwargs)[source]

Expand the energy-integrated master pattern.

Parameters:

kwargs (Any)

Return type:

tuple[NDArray[float32], NDArray[float32]]

reconstruct_bin(bin_index, **kwargs)[source]

Expand a single per-energy-bin intermediate.

Parameters:
  • bin_index (int)

  • kwargs (Any)

Return type:

tuple[NDArray[float32], NDArray[float32]]

__init__(meta, integrated_fs, bin_fs, kij, khat, pg_operators, fs_normals, bin_voltages_kv, bin_weights, site_weights=None, data=<factory>, axes=<factory>, _maps=<factory>)
Parameters:
  • meta (dict[str, Any])

  • integrated_fs (NDArray[float32])

  • bin_fs (NDArray[float32])

  • kij (NDArray[int32])

  • khat (NDArray[float32])

  • pg_operators (NDArray[float64])

  • fs_normals (NDArray[float64])

  • bin_voltages_kv (NDArray[float32])

  • bin_weights (NDArray[float32])

  • site_weights (NDArray[float32] | None)

  • data (NDArray[float32])

  • axes (dict[str, Any])

  • _maps (dict[bool, tuple[NDArray[float32], NDArray[float32], NDArray[uint8]]])

Return type:

None

ebsdsim.mploader.load_master_pattern(path)[source]

Load an ebsdsim master-pattern .npz.

Parameters:

path (str or Path) – File written by ebsdsim.save_master_pattern().

Returns:

Raw Lambert data in LoadedMasterPattern.data; call LoadedMasterPattern.lambert_data() for display scaling.

Return type:

LoadedMasterPattern

ebsdsim.mploader.build_master_pattern_data(*, integrated_fs, bin_fs, kij, pg_operators, fs_normals, hw, side, needs_southern_hemisphere, site_weights=None, normalize=None, robust_p_low=0.01, robust_p_high=0.99, interp='bilinear')[source]

Expand the fundamental sector into a dense (E, S, H, side, side) tensor.

Axes

E (energy): 1 + n_bins when n_bins > 1 (index 0 is the

energy-integrated pattern, index 1 + b is bin b); otherwise 1 (the single bin, which is also the integrated pattern).

S (site): 1 + n_sites when n_sites > 1 (index 0 is the

site-integrated pattern, index 1 + s is site s); otherwise 1 (the single site).

H (hemisphere): 2 when needs_southern_hemisphere else 1

(index 0 north, index 1 south).

The point-group pixel-source map is built once per hemisphere and shared across every energy/site channel, so the fundamental sector is expanded without redundant per-channel geometry work.

Returns (data, axes) where axes documents the index layout.

Parameters:
Return type:

tuple[NDArray[float32], dict[str, Any]]

ebsdsim.mploader.to_uint8(img01)[source]

Convert a float image in [0, 1] to uint8 [0, 255].

Parameters:

img01 (NDArray[floating])

Return type:

NDArray[uint8]

ebsdsim.mploader.save_png_gray(img_uint8, path)[source]

Write a 2-D uint8 array as an 8-bit grayscale PNG (stdlib only).

Parameters:
  • img_uint8 (NDArray[uint8])

  • path (str | Path)

Return type:

Path

Display scaling

Per-channel intensity scaling for Lambert display (not used in simulation output).

ebsdsim.normalize.scale_fs_channel(vals, normalize, *, robust_p_low=0.01, robust_p_high=0.99)[source]

Scale one fundamental-sector channel to [0, 1] for display.

Parameters:
  • normalize (Literal['minmax', 'robust'] | None) – None — return raw values (no scaling). "minmax" — divide by per-channel min/max (lossless up to float precision). "robust" — IQR outlier gate, then percentile window (lossy by default uses robust_p_low / robust_p_high).

  • robust_p_low (float) – Percentiles in [0, 1] used only when normalize="robust".

  • robust_p_high (float) – Percentiles in [0, 1] used only when normalize="robust".

  • vals (NDArray[floating])

Return type:

NDArray[float32]