PyRITE
A Python toolkit for Radiation from Interactions and Transport of Electrons.
PyRITE is a Monte Carlo electron transport code for crystalline and amorphous solids. Its transport model largely follows the well-validated PENELOPE code system. Its main purpose is to predict tunable X-ray lines emitted when electrons interact coherently with crystals: parametric X-ray radiation (PXR) and coherent bremsstrahlung (CBS). Neither PENELOPE nor Geant4 models these natively.
The longer-term goal is a general-purpose electron transport and radiation toolkit for 1 keV–100 MeV electrons, with native GPU acceleration, arbitrary source, target, and detector geometries, and extensible physics. Against the FORTRAN-based PENELOPE and the C++-based Geant4, PyRITE trades maturity for a lower barrier to entry: it is plain Python, fast, and easy to extend. Electron channeling in crystals below 100 MeV is under investigation.
- Source: https://github.com/Quantum-Light-Matter-Cooperative-QLMC/pyrite
- Documentation: https://pyrite.readthedocs.io/en/latest/
Install
Requires Python ≥ 3.13. Python 3.13 installs backports.zstd automatically;
Python 3.14+ uses the standard-library implementation.
# Command-line tool in its own environment (recommended):
uv tool install pyrite-mc
# Or into the current environment, for use as a library:
pip install pyrite-mc
# OR
uv add pyrite-mc
Then fetch the reference data and check the install:
pyrite tables fetch # pinned datasets and tables, about 100 MB
pyrite config setup # optional: detect GPU hardware, save the backend
pyrite --help
pyrite tables fetch downloads EEDL, EADL, EPDL, SBETHE, ELSEPA, and BremsLib
data from public GitHub Releases; no GitHub token is needed. Run
pyrite tables fetch --help to list the individual datasets, or
pyrite tables fetch NAME --archive PATH to install one from a local archive.
In a notebook with no terminal (for example, jupyter), call pyrite.fetch_tables(),
which does the same as a bare pyrite tables fetch.
For tab completion, run pyrite config completion install and restart the
shell; with uv tool, run uv tool update-shell first so pyrite is on
PATH. See the shell-completion guide.
GPU acceleration
The base pyrite-mc package is CPU-only. Install at most one GPU extra by
adding it in brackets after the package name:
| Hardware | Extra | Backend |
|---|---|---|
| NVIDIA | nvidia |
CUDA CuPy |
| AMD | amd |
ROCm source-built CuPy |
| Intel | intel |
oneAPI dpnp + dpctl |
uv tool install pyrite-mc[nvidia]
The amd extra builds CuPy from source and needs CUPY_INSTALL_USE_HIP=1 set
for the install command; ROCm support is entirely untested as of this writing;
Intel support is provisional, and FP64 operations are currently unsupported.
PYRITE_MC_BACKEND=auto|cpu|cuda|rocm|sycl selects the array backend. See
execution and acceleration
for backend, precision, transport-core, and memory-policy controls.
From a checkout
To work from source:
git clone https://github.com/Quantum-Light-Matter-Cooperative-QLMC/pyrite.git
cd pyrite
uv sync # creates .venv/; add --extra nvidia|amd|intel for a GPU
source .venv/bin/activate # Windows: .venv\Scripts\activate
Commands in the README and user guides assume pyrite is on your PATH:
activate .venv in each shell, or install once with uv tool install .
(see the shell-completion guide).
Contributor and CI commands are in the development workspace guide.
Run
Outputs generated using the CLI default to pyrite-output/<kind>/ in the current workspace.
For a fixed output home, run pyrite config set workspace.root /path/to/workspace
once. Subdirectories reuse the nearest existing output tree; see the
output-home and migration rules.
pyrite run executes a resumable campaign over a named profile and writes
checkpoints under pyrite-output/checkpoints/:
# Smallest end-to-end demo (~1 min on CPU); writes component checkpoints.
pyrite run quickstart
# Analyze an existing checkpoint.
pyrite app analysis launch hopg
# Pixel-detector observations, and case / cross-material comparison.
pyrite app pixels launch hopg
pyrite app compare launch hopg
# Interactive transport and lattice viewer; no checkpoint required.
pyrite app viewer launch hopg
# Validation dashboard.
pyrite app validation launch
Full sweeps are heavy. Run them through
PyRITE's remote workflow or the portable
SLURM templates documented there. GPT .gdf electron-beam snapshots can be used
as a beam source; see GDF beam import.
Profiles
A profile is a named campaign: thickness, energy, and tilt grids, electron counts, beam and detector references, and material membership. PyRITE ships light demo profiles that each exercise one feature and run locally in a minute or two on CPU:
| Demo | Shows |
|---|---|
quickstart |
one HOPG case, incoherent PXR lines plus bremsstrahlung |
sweep_demo |
a small two-material energy x tilt sweep for the analysis app |
trajectory_demo |
--trajectories capture and VTK export |
coherent_demo |
coherent + incoherent emission in windowed line grids |
detector_demo |
a pixel detector behind a filter, with Poisson counts |
pixelated_detector_demo |
native Timepix3 pixel grid with ideal response and expected counts |
two_detector_demo |
two ideal scalar apertures at 90° and 135°, exposing raw spectra |
high_energy_demo |
a 1 MeV beam with the measured line-grid policy |
hopg_emittance_demo |
Courant-Snyder transverse beam phase space |
standard is also bundled: it is the catalog's base profile, which every
material's default scan ranges resolve from, and a full research-scale sweep.
pyrite profile list
pyrite profile show quickstart
pyrite profile numerics show quickstart
Bundled profiles are read-only. Profiles you create or edit live in your user
catalog layer, profiles/NAME.toml under the platform config directory
(~/.config/pyrite/ on Linux; pyrite config get catalog.user), and are read
over the bundled catalog:
# Clone a demo, then replace its energy (keV) and thickness (Å) grids.
pyrite profile create my_scan --from quickstart --energy 30:60:10 --thickness 5000,20000
pyrite profile set my_scan --material hopg,hbn
pyrite profile numerics set my_scan --cxr-trials 2000
pyrite profile show my_scan
pyrite run my_scan -m hopg
A complete catalog of your own (materials, beams, detectors) is selected with
pyrite config set catalog.path DIR; profile edits then write there instead.
See sweep profiles, external catalogs, and the profile settings map for every field.
Python API
For a single simulation with no files on disk, Physics chooses models and
Numerics controls sampling, energy grids, and execution:
import pyrite as pr
beam = pr.Beam(
energy_keV=30.0, transverse=pr.TransverseSpot(fwhm_x_mm=1.0), longitudinal=pr.PointBunch()
)
target = pr.Slab("hopg", thickness_ang=10_000.0, tilt_deg=30.0, footprint=pr.Footprint(5.0, 5.0))
detector = pr.Detector()
result = pr.simulate(
beam,
target,
detector,
physics=pr.Physics(),
numerics=pr.Numerics(cxr_trials=450, brem_trials=100),
)
print(result.provenance["identity_digest"])
With the scalar Detector shown here, simulate returns emitted spectra in
photons per incident electron per eV per sr, plus run identification, and
neither reads nor writes a checkpoint. Detector response is not applied; apply
it to the spectra explicitly if needed. The
Python API workflow covers scenes,
sweeps, detector scoring, and persistence. Prefer pyrite run when you need
resumability, profiles, remote execution, or the analysis apps.
The generated CLI reference documents every command.
Core physics
Pipeline: sampled electron beam → single-scattering electron transport → per-segment PXR + CBS, incoherent bremsstrahlung, and characteristic lines → photon escape → detector scoring.
- Electron transport: independent piecewise-linear flights with explicit elastic collisions and condensed energy loss; deterministic by default, with optional Urban straggling. Elastic collisions sample ELSEPA partial-wave cross sections; collision stopping uses material-level SBETHE tables. Beamline space charge and secondary electrons are not modeled.
- Crystal source: phase-specific structures, complex atomic form factors, Debye-Waller factors, selected reflections, and optional mosaicity define the reciprocal-space coupling.
- Coherent lines: first-order kinematic Born PXR and CBS amplitudes are summed coherently within each transport segment, i.e. between elastic collisions that change the electron direction $\hat{\mathbf v}$. A collision-free flight may be subdivided to resolve CSDA energy and clock evolution; each segment uses one representative velocity. The in-medium Bragg resonance is $\omega = (\mathbf v\cdot\mathbf g)/[1 - \mathrm{Re}\lbrace n(\omega)\rbrace,\hat{\mathbf n}\cdot\mathbf v]$. Dynamical diffraction and electron channeling are not modeled.
- Incoherent continuum:
the default is the direction-resolved BremsLib v2.0 double-differential cross
section (
pyrite tables fetch bremslib). Without those tables, a run warns and falls back to isotropic EEDL bremsstrahlung: the ENDF-6 MF=23/MT=527 total cross section times the normalized MF=26/MT=527 photon-energy density, also selectable asbremsstrahlung_model="eedl". Unscreened Born Bethe-Heitler with an Elwert correction remains an optional backend. - Characteristic lines: electron-impact vacancies from EEDL subshell ionization cross sections relax through xraydb fluorescence yields with L-shell Coster-Kronig redistribution. Each line carries its natural-width Lorentzian and is scored as a separate incoherent component of the line spectrum.
- Photon transport: straight-ray Beer-Lambert escape with the total narrow-beam coefficient (photoabsorption plus Rayleigh and Compton removal). Scattered photons leave the ray with no build-up, redirection, or re-emission; bulk refractive dispersion is passive; interface optics are omitted.
- Detector treatment: source spectra are evaluated in a fixed far-field direction. Solid-angle acceptance, aperture broadening, efficiency, and measured-energy redistribution are downstream steps.
By default PyRITE neglects interference between distinct flights and between
incident electrons. The optional
coherent/both tracking policy
keeps phase along each single-electron trajectory and adds inter-electron terms
weighted by the sampled bunch form factor.
The physics model index lists assumptions, model variants, and conventions, with links to each implementation-level description. Geometry follows the tilt convention.
Data and outputs
src/pyrite/data/catalog/ is the bundled catalog: crystals, media, materials,
beams, detectors, and demo profiles, one TOML file per object. Your own
profiles and their energy-grid artifacts live in the user catalog layer
(catalog.user). Settings live in ~/.config/pyrite/config.toml, remembered
app state in ~/.local/state/pyrite/, fetched data in ~/.local/share/pyrite/,
and rebuildable caches in ~/.cache/pyrite/ (platform equivalents elsewhere). Phase-specific CIFs
live in src/pyrite/data/cifs/; loading is offline. pyrite material validate
checks the selected catalog.
Each checkpoint is pyrite-output/checkpoints/<stem>/{line,brem,characteristic}.h5 plus a
pyrite-output/checkpoints/<stem>/meta.json manifest. Stored source spectra exclude detector
response unless a detector view applies it explicitly.
Validation
The analytic core is cross-checked against Feranchuk et al. (2000) and Zhai et al. (2025). Before scientific use, consult the validation ledger for claim-level status and the validation methodology.
References
Primary physics and data sources:
- I. D. Feranchuk, A. Ulyanenkov, J. Harada, and J. C. H. Spence, Parametric x-ray radiation and coherent bremsstrahlung from nonrelativistic electrons in crystals, Phys. Rev. E 62, 4225 (2000). doi:10.1103/PhysRevE.62.4225
- Q. Zhai et al., Enhanced tunable X-rays from bulk crystals driven by table-top free electron energies, Nat. Commun. 16, 11218 (2025). doi:10.1038/s41467-025-66063-6
- F. Salvat, PENELOPE-2024: A Code System for Monte Carlo Simulation of Electron and Photon Transport, OECD NEA report NEA/MBDAV/R(2024)1 (2025).
- F. Salvat, A. Jablonski, and C. J. Powell, ELSEPA — Dirac partial-wave calculation of elastic scattering of electrons and positrons by atoms, positive ions and molecules, Comput. Phys. Commun. 165, 157 (2005). doi:10.1016/j.cpc.2004.09.006
- A. Poškus, Double and single differential cross sections of electron-atom bremsstrahlung at electron energies up to 30 MeV for Z = 1–100, At. Data Nucl. Data Tables 166, 101734 (2025). doi:10.1016/j.adt.2025.101734
The full bibliography (atomic data libraries, stopping powers, form factors,
and numerical methods) is on the
published references page,
generated from docs/references.bib.
Status and license
Academic research code under active development, distributed under the UCLA Academic Software License for educational or academic research use by academic or nonprofit researchers. For commercial licensing, contact the author listed in the license.
Metadata
Release files for pyrite-mc 0.13.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pyrite_mc-0.13.5.tar.gz | 9.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pyrite_mc-0.13.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 11.0 MB
Release files / pyrite_mc-0.13.5.tar.gz
| Download URL | pyrite_mc-0.13.5.tar.gz |
|---|---|
| Size | 9.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
077f61c7970ad06b15bb12bbf16a4f8ade3f81f10d4451e1d6a6d4838a7d01cb
|
|
BLAKE2b-256 checksum How to use checksums |
268919c9a544300feb8915dfc6914f5b41056b5d125239296a239c5f6b298a3c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency logRelease files / pyrite_mc-0.13.5-py3-none-any.whl
| Download URL | pyrite_mc-0.13.5-py3-none-any.whl |
|---|---|
| Size | 1.9 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
414cb068ece4c753cdd3d42f6b53003848760b9ca556fb07e227b2a55ccffd70
|
|
BLAKE2b-256 checksum How to use checksums |
41600e6bed256207e134fc87390613cd4ece15279dffe45d47c0a347378dd978
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.
Transparency log