Nuclear data as Parquet — queryable with DuckDB
Project description
nucl-parquet
Nuclear data as Parquet files — cross-sections, stopping powers, decay data, and isotopic abundances from all major evaluated libraries. Queryable with DuckDB, Polars, Pandas, or any Arrow-compatible tool.
Installation
pip install nucl-parquet
The pip package is a thin loader (~50 KB). Data files are either cloned from the git repo or downloaded from GitHub Releases:
import nucl_parquet
# Download data to ~/.nucl-parquet/ (first time only)
nucl_parquet.download()
Or clone the repo directly for the full dataset:
git clone https://github.com/exoma-ch/nucl-parquet.git
export NUCL_PARQUET_DATA=/path/to/nucl-parquet/data
Usage
import nucl_parquet
db = nucl_parquet.connect()
# Cross-section query
db.sql("SELECT * FROM tendl_2024 WHERE target_A=63 AND residual_Z=30")
# Compare all libraries
db.sql("SELECT library, energy_MeV, xs_mb FROM xs WHERE target_A=63 AND residual_Z=30")
# Decay chain
db.sql(nucl_parquet.DECAY_CHAIN_SQL, params={"parent_z": 92, "parent_a": 238})
# Stopping power — light ions (NIST PSTAR/ASTAR/ESTAR)
nucl_parquet.elemental_dedx(db, "p", 29, 10.0) # protons in Cu at 10 MeV
nucl_parquet.elemental_dedx(db, "e", 29, 1.0) # electrons in Cu at 1 MeV
nucl_parquet.compound_dedx(db, "p", [(29, 0.5), (30, 0.5)], 10.0)
# Stopping power — heavy ions (CatIMA, any isotope of Z=1-92)
nucl_parquet.elemental_dedx(db, "c12", 6, 12 * 100.0) # C-12 in C at 100 MeV/u
nucl_parquet.elemental_dedx(db, "pb208", 82, 208 * 50.0) # Pb-208 in Pb at 50 MeV/u
nucl_parquet.elemental_dedx(db, "xe132", 14, 132 * 50.0) # Xe-132 in Si at 50 MeV/u
# Heavy-ion total reaction cross-sections (Tripathi 1997)
db.sql("SELECT * FROM hi_xs WHERE target_Z=29 ORDER BY energy_MeV") # c12 on Cu
db.sql("""
SELECT energy_MeV, energy_MeV/12 AS energy_MeV_u, xs_mb
FROM hi_xs WHERE target_Z=6
""") # c12 on C — typical carbon therapy channel
# Heavy-ion production cross-sections (Geant4 INCL++/ABLA07)
# σ(Zf, Af, E) per residual isotope — 6 projectiles × 92 targets × ~60 energies
db.sql("""
SELECT residual_Z, residual_A, energy_MeV, xs_mb
FROM hi_xs_prod
WHERE target_Z=29 AND library='hi-xs-prod'
ORDER BY residual_Z, residual_A, energy_MeV
""") # all C-12 fragmentation products on Cu
Data resolution
connect() finds data in this order:
- Explicit
data_dirargument $NUCL_PARQUET_DATAenvironment variable- Sibling repo checkout (when running from source)
~/.nucl-parquet/(downloaded vianucl_parquet.download())
Why Parquet instead of ENDF-6?
The ENDF-6 format dates from the 1960s. It was designed for Fortran on punch cards: 80-character fixed-width records, implicit column positions, and a cryptic MF/MT numbering system.
| ENDF-6 | Parquet | |
|---|---|---|
| Format | Fixed-width Fortran text, 80-char cards | Columnar binary, self-describing schema |
| Parsers needed | Specialized (NJOY, PREPRO, FUDGE, endf pkg) |
Any language — Python, R, Julia, Rust, JS, SQL |
| Random access | Sequential parse from start | Predicate pushdown, skip irrelevant row groups |
| Compression | None (or gzip'd text) | zstd columnar compression (5-10x smaller) |
| Cross-library comparison | Convert each library separately first | SELECT * FROM '*/xs/p_Cu.parquet' |
| Browser/WASM | Not feasible | Works natively (DuckDB-WASM, Pyodide) |
Size comparison for the same data:
| Library | ENDF-6 (zipped) | Parquet (zstd) | Reduction |
|---|---|---|---|
| TENDL-2025 neutron | ~800 MB (2850 zip files) | 25 MB | 32x |
| ENDF/B-VIII.1 (all) | ~120 MB | 4.3 MB | 28x |
| JENDL-5 (all) | ~200 MB | 8.6 MB | 23x |
Libraries included
| Library | Projectiles | Source |
|---|---|---|
| TENDL-2024 | n, p, d, t, ³He, α | IAEA/PSI |
| TENDL-2025 | n, p, d, t, ³He, α | PSI |
| ENDF/B-VIII.1 | n, p, d, t, ³He, α | NNDC/BNL |
| JEFF-4.0 | n, p | NEA |
| JENDL-5 | n, p, d, α | JAEA |
| CENDL-3.2 | n | CIAE |
| BROND-3.1 | n | IPPE |
| FENDL-3.2 | n | IAEA |
| EAF-2010 | n | CCFE |
| IRDFF-II | n | IAEA |
| IAEA-Medical | p, d | IAEA |
| EXFOR | n, p, d, t, ³He, α | IAEA NDS (experimental) |
| HI-XS (Tripathi 1997) | p, ⁴He, ¹²C, ¹⁶O, ²⁰Ne, ²⁸Si, ⁴⁰Ar, ⁴⁰Ca, ⁵⁶Fe, ⁵⁸Ni, ¹³²Xe, ²⁰⁸Pb | semi-empirical (Tripathi 1997) |
| HI-XS Production (Geant4 INCL++/ABLA07) | ¹²C, ¹⁶O, ²⁰Ne, ²⁸Si, ⁴⁰Ar, ⁵⁶Fe | Geant4 11.3.2 Monte Carlo |
Parquet schemas
Evaluated cross-sections ({library}/xs/*.parquet):
| Column | Type | Description |
|---|---|---|
| target_A | Int32 | Target mass number |
| residual_Z | Int32 | Product atomic number |
| residual_A | Int32 | Product mass number |
| state | Utf8 | Isomer state: "", "g", "m" |
| energy_MeV | Float64 | Projectile energy in MeV |
| xs_mb | Float64 | Cross-section in millibarn |
EXFOR experimental (exfor/*.parquet):
| Column | Type | Description |
|---|---|---|
| exfor_entry | Utf8 | EXFOR accession number |
| target_Z | Int32 | Target atomic number |
| target_A | Int32 | Target mass number (0 = natural) |
| residual_Z | Int32 | Product atomic number |
| residual_A | Int32 | Product mass number |
| state | Utf8 | Isomer state |
| energy_MeV | Float64 | Projectile energy in MeV |
| energy_err_MeV | Float64 | Energy uncertainty (nullable) |
| xs_mb | Float64 | Cross-section in millibarn |
| xs_err_mb | Float64 | Cross-section uncertainty (nullable) |
| author | Utf8 | First author |
| year | Int32 | Publication year |
Stopping powers (stopping/{source}.parquet — one file per source):
| Column | Type | Description |
|---|---|---|
| source | Utf8 | PSTAR, ASTAR, ESTAR, dSTAR, tSTAR, He3STAR, catima_C12, … |
| target_Z | Int32 | Target element Z (1–92) |
| energy_MeV | Float64 | Projectile kinetic energy (MeV, total) |
| dedx | Float64 | Mass stopping power (MeV cm²/g) |
Files: PSTAR.parquet, ASTAR.parquet, ESTAR.parquet, dSTAR.parquet, tSTAR.parquet, He3STAR.parquet, and catima_{beam}.parquet for C12/O16/Ne20/Si28/Ar40/Fe56. The full 92×92 CaTiMA matrix (MeV/u units) lives separately at stopping/catima/catima.parquet.
dSTAR, tSTAR, and He3STAR are velocity-scaled from PSTAR/ASTAR — exact for electronic stopping since Z_proj and velocity fully determine dE/dx. For elements not in the NIST table (e.g. Ra, Rn, Ac, Po, Fr, At, Tc, Pm), elemental_dedx() automatically falls back to CaTiMA (Bethe-Bloch), which covers all Z=1–92.
Heavy-ion total reaction cross-sections (hi-xs/xs/{proj}_{target}.parquet):
Tripathi (1997) semi-empirical parameterization — total reaction cross-sections for all 12 projectiles against all 92 target elements. Energy stored as total MeV for the projectile; 1–1000 MeV/u range, 60 log-spaced points.
| Column | Type | Description |
|---|---|---|
| target_Z | Int32 | Target atomic number (1–92) |
| target_A | Int32 | Target mass number (most-abundant stable isotope) |
| energy_MeV | Float64 | Total projectile kinetic energy (MeV) |
| xs_mb | Float64 | Total reaction cross-section (mb) |
Heavy-ion production cross-sections (hi-xs-prod/xs/{proj}_{target}.parquet):
Geant4 11.3.2 FTFP_INCLXX physics list (INCL++ cascade + ABLA07 de-excitation) — per-isotope fragment production cross-sections σ(Zf,Af,E) in mb, normalized to Tripathi (1997) σ_R. Covers C-12, O-16, Ne-20, Si-28, Ar-40, Fe-56 projectiles against all 92 target elements, ~60 log-spaced energy points from 1–1000 MeV/u.
| Column | Type | Description |
|---|---|---|
| proj_Z | Int32 | Projectile atomic number |
| proj_A | Int32 | Projectile mass number |
| target_Z | Int32 | Target atomic number (1–92) |
| target_A | Int32 | Target mass number (most-abundant stable isotope) |
| residual_Z | Int32 | Fragment atomic number |
| residual_A | Int32 | Fragment mass number |
| energy_MeV | Float64 | Mean actual reaction vertex energy (MeV total) |
| xs_mb | Float64 | Production cross-section (mb) |
Heavy-ion stopping powers (stopping/catima.parquet):
Full 92×92 matrix — all projectile elements Z=1–92 against all target elements Z=1–92, computed with CatIMA. Energy stored in MeV/u; isotope-independent (divide total MeV by A to look up).
| Column | Type | Description |
|---|---|---|
| proj_Z | Int32 | Projectile atomic number (1–92) |
| target_Z | Int32 | Target atomic number (1–92) |
| energy_MeV_u | Float64 | Kinetic energy per nucleon (MeV/u) |
| dedx | Float64 | Mass stopping power (MeV cm²/g) |
Development
# Install dev dependencies
uv sync --dev
# Run unit tests (no data needed)
uv run pytest tests/test_loader.py -v
# Run full test suite (requires data)
uv run pytest tests/ -v
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nucl_parquet-0.8.1.tar.gz.
File metadata
- Download URL: nucl_parquet-0.8.1.tar.gz
- Upload date:
- Size: 39.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
314ebb345f1904f8081af9ae9e86cac4fb1334f1db52c212d6a40e28694ce501
|
|
| MD5 |
fad66409db46a58ac78e9406c4ece16b
|
|
| BLAKE2b-256 |
8c8c8f053fe0bc732d20d0c844bfec66378e537390f975a9caab049d45cc5ebf
|
Provenance
The following attestation bundles were made for nucl_parquet-0.8.1.tar.gz:
Publisher:
release.yml on exoma-ch/nucl-parquet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nucl_parquet-0.8.1.tar.gz -
Subject digest:
314ebb345f1904f8081af9ae9e86cac4fb1334f1db52c212d6a40e28694ce501 - Sigstore transparency entry: 1179228367
- Sigstore integration time:
-
Permalink:
exoma-ch/nucl-parquet@061425c1248ba370627094487eab71bf2f0af665 -
Branch / Tag:
refs/tags/v0.8.1 - Owner: https://github.com/exoma-ch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@061425c1248ba370627094487eab71bf2f0af665 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nucl_parquet-0.8.1-py3-none-any.whl.
File metadata
- Download URL: nucl_parquet-0.8.1-py3-none-any.whl
- Upload date:
- Size: 37.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a184cc95bb3d926c48b6b8a08f79e88a36aaf7a081612010f4b3602cf03d5a7
|
|
| MD5 |
6674c306a0be29f466322606fcd6c9ac
|
|
| BLAKE2b-256 |
7996ea021c9dd7c7b9472d858fe6b997ccb39761a73c233c4da44d35a00ee790
|
Provenance
The following attestation bundles were made for nucl_parquet-0.8.1-py3-none-any.whl:
Publisher:
release.yml on exoma-ch/nucl-parquet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nucl_parquet-0.8.1-py3-none-any.whl -
Subject digest:
6a184cc95bb3d926c48b6b8a08f79e88a36aaf7a081612010f4b3602cf03d5a7 - Sigstore transparency entry: 1179228405
- Sigstore integration time:
-
Permalink:
exoma-ch/nucl-parquet@061425c1248ba370627094487eab71bf2f0af665 -
Branch / Tag:
refs/tags/v0.8.1 - Owner: https://github.com/exoma-ch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@061425c1248ba370627094487eab71bf2f0af665 -
Trigger Event:
push
-
Statement type: