Deep, code-cited reference. See the readable summary for the public version. This page is the full provenance; a Verification addendum (run
wf_7fbcd118-848, 2026-06-08) at the bottom lists every point where the code differs from this text.
Per-element offset fitting — provenance + procedure
Generating script: benchmark/fit_per_element_reference.py
(12.9 KB, written 2026-05-11 03:04)
Output CSVs (both written 2026-05-11 03:30 — single-shot run, ~26 min after script saved):
FM_MatBench_grace_offsets.csv— per-element Δμ from two methods (2.6 KB)FM_MatBench_grace_per_element_rmse_corrected.csv— per-element RMSE/MAE/ME under each correction (8.7 KB)
Both CSVs live in benchmark/.
Run command
cd .../Benchmark_Potential/benchmark
python fit_per_element_reference.py FM_MatBench_grace
# Defaults to FM_MatBench_grace if no arg. Pass any other potential name to re-run.
Output paths are hardcoded as:
{POT}_offsets.csv{POT}_per_element_rmse_corrected.csv
No execution log was saved; the timestamp gap implies a single interactive run.
Data source
- DB:
dft_surrogate_mlip_assyst(hostdb-host:db-port) — not gbsegbench - Query: join
mlip_calctostructurefor the given potential, status='done',energy IS NOT NULL,dft_energy IS NOT NULL - Outlier filter: drop rows with
|(m.energy - s.dft_energy) / s.n_atoms| ≥ 50 eV/atom(MLIP numerical failures, not real reference offsets) - Streaming: server-side named cursor, 50,000-row chunks (~7M rows total for FM_MatBench)
The two offset methods
Unary (unary_mu)
For each element e, average the per-atom delta over structures of formula e_N only:
Δμ_e = mean( (E_MLIP − E_DFT) / N ) over single-element structures
Simple but ignores ~all multi-element data and gives NaN for elements never observed in unary form.
Global (global_mu)
Solve simultaneously for all elements via least squares:
(E_MLIP − E_DFT) = Σ_i N_i · Δμ_i for every structure
Built into an n_elem × n_elem normal-equation system (AᵀA · μ = Aᵀb) by accumulating V.T @ V and V.T @ b per chunk, where V[k,i] = N_i for structure k. Solved with np.linalg.solve(AᵀA + 1e-9·I, Aᵀb) (small Tikhonov regulariser to handle rare or unary-only elements).
Algorithm (two passes)
Pass 1 — accumulate:
- Per-element unary sum + count →
unary_mu - Normal-equation matrices
AᵀA,Aᵀb→ solve formu_global - Per-element raw residual SSE / SAE / SD → raw RMSE / MAE / ME
Pass 2 — re-stream the same rows, compute corrected residuals:
corr_g = V @ mu_global(works for all rows)corr_u = V @ mu_unary_filled(only valid where every element in the formula has a unary fit; tracked viaunary_safemask)- Per element: corrected SSE / SAE / SD under each correction, divided by count → corrected RMSE / MAE / ME
Output CSV schemas
{POT}_offsets.csv
| column | meaning |
|---|---|
element |
element symbol |
unary_n |
number of unary structures of this element |
unary_mu |
unary-method Δμ in eV/atom (empty if no unary data) |
global_mu |
global-method Δμ in eV/atom |
Sample rows from FM_MatBench_grace_offsets.csv:
element,unary_n,unary_mu,global_mu
Ac,36486,-0.086873,-0.079247
Ag,19478,-0.012269,-0.008958
Al,58882,0.012017,-0.002053
Am,0,,0.000000
{POT}_per_element_rmse_corrected.csv
| column | meaning |
|---|---|
element |
element symbol |
n |
structures contributing to raw/global stats |
raw_{rmse,mae,me} |
per-element error of (E_MLIP − E_DFT) / N with no correction |
uni_{rmse,mae,me} |
error after subtracting Σ N_i · unary_mu_i |
uni_n |
structures contributing to unary-corrected stats (= n minus those touching elements without a unary fit) |
glb_{rmse,mae,me} |
error after subtracting Σ N_i · global_mu_i |
All in eV/atom.
Sample rows:
element,n,raw_rmse,raw_mae,raw_me,uni_rmse,uni_mae,uni_me,uni_n,glb_rmse,glb_mae,glb_me
Ac,36486,0.353836,0.103741,-0.086873,0.343006,0.079391,-0.000000,36486,0.343090,0.077194,-0.007626
Ag,19478,0.702932,0.163635,-0.012269,0.702825,0.156259,0.000000,19478,0.702832,0.158218,-0.003311
Al,169714,0.877374,0.126958,-0.055058,0.873305,0.086304,-0.010454,169714,0.873263,0.076767,0.002512
Ar,38929,2.246682,0.717178,-0.678208,2.141871,0.965469,0.000000,38929,2.144428,0.891763,-0.104683
Provenance chain
- DFT ground truth — 7M structures in
dft_surrogate_mlip_assyst.structure.dft_energy(from the ASSYST campaign; seewiki/mlip-benchmark-fmmatbench-assyst.md). - MLIP single-point eval —
FM_MatBench_gracerows landed inmlip_calcvia the FM_MatBench worker pipeline. - Offset fit (2026-05-11) —
fit_per_element_reference.py FM_MatBench_gracestreamed the DB and wrote both CSVs.
Reusing the script for other potentials
The script accepts the potential name as sys.argv[1]:
python fit_per_element_reference.py FM_MatBench_orb
python fit_per_element_reference.py FM_MatBench_mace
# … etc
It will write {POT}_offsets.csv and {POT}_per_element_rmse_corrected.csv into the benchmark directory. No code changes needed.
To apply this to gbsegbench data instead of ASSYST:
Change the DSN at the top of fit_per_element_reference.py:
DSN = "host=db-host port=db-port dbname=dft_surrogate_mlip_gbsegbench"
Also note: gbsegbench's structure table may not have dft_energy and element columns in the same shape as ASSYST — verify the schema before running.
Verification addendum (run wf_7fbcd118-848, 2026-06-08)
This offset-provenance doc describes the earlier global/unary offset path
(fit_per_element_reference.py). The production headline offsets are fit by
fit_offsets_systemspin.py (per-(composition-system × ISPIN) robust MAD σ-clip → the
_corrected_global/_corrected_elemental columns). The DFT settings on the hub use the
production INCAR (ALGO=Normal, KPAR=4, EDIFFG=1e-4, NSW=300/NELM=300, ENCUT=400,
ISMEAR=1/SIGMA=0.2, PREC=Accurate, AMIX 0.01 / AMIX_MAG 0.1 / BMIX,BMIX_MAG 1e-4); MAGMOM is
set per-structure. Perturbation counts are 5 RATTLE + 5 TRIAX + 5 SHEAR = 15/base, and the
force rows obey the same 5 eV/atom + 10 eV/Å per-structure cut as energies (maintainer-confirmed).
The single-atom 2×2×2 supercell expansion in the structure filter is dead code
(structure_filter_utils.py:91,143,147).