Secondary-photon fit form quality across 21 materials
This is a regression-testing harness rather than an analytic verification
script. It exists to answer the question "is my coupled-photon
B_p(τ) fit form good enough across the materials this library is
likely to be applied to?", and is the tool that was used to design the
shipped Form K_reg fit.
Setup
The cache file verification_and_validation/secondary_photon_fit_cache.json
holds 6 training anchors plus 1 held-out anchor for each of 21
shielding materials, generated with compute_buildup against
ENDF/B-VIII.1 with weight windows on. Materials span:
- Hydrogenous moderators: polyethylene, polyethylene_deep, borated_poly, lih, d2o, h2o_water (pure water).
- Mixed light/heavy composites: WC + 20/50/70 vol% water, WB + 20/50/70 vol% water (peak-and-decay \(B_p\)).
- Saturating heavy attenuators: concrete, steel, ss316, tungsten, lead, magnetite (heavy concrete), b4c, aluminum, concrete_steel10.
Per material, the held-out anchor sits ~30-50% past the deepest training anchor.
What the harness reports
For each candidate fit form in CANDIDATES, for every material:
- Training fit z-score —
max |B_pred - B_mc| / σover the 6 training anchors. Catches in-sample over-/under-fitting. - Holdout z-score —
|B_pred - B_mc| / σat the held-out anchor. Catches over-fitting that hides in training but shows up in extrapolation.
Aggregated across the 21 materials:
| Current shipped form (Power × sat, 3p) | Form K_reg (5p, L2) | |
|---|---|---|
| Worst holdout z | 54.3 | 36.6 |
| Mean holdout z | 14.7 | 6.0 |
| Median holdout z | 7.1 | 2.4 |
| Worst training z | 42.4 | 3.3 |
K_reg dominates baseline on every metric. The wins come from the
late-stage exponential growth tail (exp(d·x_n + e·x_n²) with signed
d, e) which baseline's pure power-law saturation cannot represent.
Running
The script also writes:
secondary_photon_fit_dataset.csv— flat (material, τ, descriptors, B_p, σ) CSV ready for symbolic regression or external analysis (gitignored)./tmp/secondary_photon_fit_suite_plot.png— per-material comparison panels.
Adding a new candidate form
Drop a (fit_fn, eval_fn) pair into the CANDIDATES dict in
secondary_photon_fit_test_suite.py. Re-run; the harness scores it across all
21 materials and prints the per-material residuals plus the worst /
mean / median holdout z.
Same machinery for flux
The harness loads the dose-AP-coupled-photon field per material. The
secondary-photon flux is fit with the same Form K_reg in the shipped
library; to validate that path:
- Regenerate the cache including the flux quantity:
compute_buildup(quantities=["dose-AP-coupled-photon", "flux-coupled-photon"], ...). - In
_load(), swap the read ofr["mc"]["dose-AP-coupled-photon"]forr["mc"]["flux-coupled-photon"](and the matchingpk,mc_std_dev).
Same applies for the neutron and primary-photon sibling harnesses.