You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mg Kα about 300 counts low, Si 8.7 % low, σ 5 to 12 % small; Mg missed in 37 of 38 Al-Mg-Si files. Diagnose on the Al matrix of a real Al-Mg-Si map (pixels whose Mg and Si are below L_D) as the in-situ standard. Known issue: offset and gain trade off on lines that span little of the axis (AxisGateTests.testE3RefinementRecoversPlantedOffsetAndGain).
Diagnosis done locally on the owner's data; the data and every number measured on it stay private. No kit change in this round: no single kit defect with a clear fix was found.
What the experiment separated, in general terms:
The Mg miss follows the energy axis: on the file calibration the non-negative fit holds Mg K-alpha at zero; with the axis and the detector width refined it is found. The proposer-side change is feat: the proposer refines the energy axis on its own K picks #47.
The Si deficit follows the default continuum between the Al K edge and about 2.2 keV (one low-order segment above the Al edge). Splitting the continuum at the Si K edge (1.839 keV) removes the residual structure on real data, but on the public planted pool eds-absorption-truth.json (no detector Si edge) the same split triples the Si sigma and moves Si by -4 % to +19 % depending on the order, so it is not shipped as a default. FitPolicy.continuumEdges / continuumOrders already let a consumer choose it.
The Al K-alpha tail and the Al K-beta weight are second-order effects here.
Next: a physical detector Si-edge term in the continuum (no free polynomial freedom under Si K-alpha), tested on a planted spectrum that has a dead-layer step, then measured on a Si-free standard. All results stay validation: "none".
Checked on the public AlMgSi demo set (demo-edx, generator sim_edx.py v2.0, seed 42, ladder seed 52), which carries planted truth on synthetic data: recipe compositions, the true k, four-segment absorption, a 1.5 % Al K-alpha tail (0.12 keV), Si internal fluorescence, Si escape, sum peaks (parents lose the photons) and stray Cu K. No detector dead layer is planted.
Pipeline: PooledQuantifier.run with the true k typed, the truth geometry and thickness, absorption on, the true axis locked. Each pool was fitted twice: the Poisson data, and the noise-free expected spectrum x100 (the fit bias without noise). Si planted counts include the Si internal-fluorescence peak (the kit convention).
Default fit (exSpy-equivalent: one Gaussian per line, no sum peaks), net against planted, noise-free:
pool
Mg
Si
kit fixture eds-absorption-truth.json (recipe A, 1e4 px)
-32 %
-18 %
map, all matrix recipes (2897 px)
-45.5 %
-16.6 %
map, recipe A (1217 px)
-32 %
-15 %
ladder L5 (recipe A, high rate)
-57 %
ladder L6 (precipitate end-on)
+0.5 %
-8.4 %
ladder L7 (pure Mg5Si6)
+0.1 %
-0.2 %
At% on the data: matrix map Mg 0.44 / Si 0.45 against 0.60 / 0.60 truth; L5 Si 0.36 against 0.60.
The Si deficit follows the unmodelled sum peaks, not a dead layer. The Al+Al sum peak (2.97 keV) and the other sum peaks pull the continuum segment above the Al K edge; under least squares that lowers Si K-alpha. The cheap refuting experiment was to switch on SumEscapeModel(sumPeaks: true) and see whether Si stays biased. It does not: noise-free Si goes from -18.2 % to -4.0 % on the fixture, -16.6 % to -3.9 % on the matrix map, -14.9 % to -3.6 % on recipe A, -57 % to -8 % on L5 and -8.4 % to -1.2 % on L6. Reduced chi2 on the x100 spectra falls from 120-3000 to 0.04-8.
The earlier diagnosis on real data placed the Si deficit in the continuum between the Al K edge and 2.2 keV. On synthetic data the deficit follows the sum peaks instead, so the dead layer and a Si-free standard are no longer the next step here.
Dead-layer term (#50). A typed 0 um reproduces the default fit exactly. Fitted on this detector, which has no dead layer, it reads 0.17-0.43 um and moves Si further down in every Al pool: noise-free matrix map from -16.6 % to -23.8 %, L5 from -57 % to -75 %. On the pure beta'' pool it is neutral. The fitted thickness absorbs the sum-peak misfit, so it should be fitted only together with the sum-peak model, or typed.
Absorption correction: right. On L7 the corrected Mg/Si pull is -0.4 and the uncorrected one 5.0.
Next step: the pooled path models sum peaks when the data call for it, keeps the exSpy-equivalent fit as a switch, and pins these demo numbers as regression tests (PR to follow). Results stay validation: "none": the truth is synthetic.
The continuum at the Al K edge on a real Si-free spectrum: diagnosis and #64
Data: Snelson, Collins and MacArthur (2026), Elemental tomography dataset of Mg-Al-Ca alloy, University of Leeds, https://doi.org/10.5518/1826, licence CC BY 4.0. File Al_Wedge_Standard/Al_EDS-HAADF.emd: Titan G2 at 200 kV, Super-X. Pool of 214 793 px, 3e5 Al K-alpha counts, the refined axis from #15.
Cause. There are two parts.
The default continuum jumps between the channels at 1.559 and 1.564 keV. A detector cannot record a jump: the edge is convolved with the resolution, about 75 eV FWHM at 1.56 keV. The tabulated Al K-beta line also sits at the edge energy, so the jump trades with that line.
The order-5 segment above the edge, spanning 1.56-20 keV, cannot follow the steep shape just above the edge.
What would refute part 1: broadening the step leaves the misfit unchanged. It does not; it halves it.
continuum
model drop minus data drop across the edge channels
exSpy 0.3.2 has no edge in its background: it fits a polynomial (order 6) across the whole range. The step is the kit's own design, and no parity path is involved.
The detector dead layer (#50) is not the lever here. The data show no step at 1.839 keV, and the 10 nm Al contact layer of the generic SDD model gives about a 1 % step at the Al edge.
Synthetic check, generated in the test. An Al film whose edge is convolved with the detector, 3e5 Al K-alpha, weak Si K-alpha 2000 counts, noise-free:
film step above the edge
Si sharp
Si broadened
Si broadened, orders (9, 9)
11 %
-15.7 %
-11.3 %
-2.4 %
30 %
-38.7 %
-25.4 %
-8.0 %
The AlMgSi demo (sim_edx.py v2.0, noise-free pools ×100, true axis; planted truth on synthetic data) plants an unbroadened step:
pool
Si sharp → broadened
with sum peaks
Mg sharp → broadened
recipe A
-17.2 → -16.2 %
-6.2 → -3.5 %
-32.0 → -29.8 %
all matrix
-18.8 → -17.9 %
-6.4 → -3.6 %
-31.8 → -29.7 %
precipitate end-on
-3.2 → -3.2 %
-3.0 → -3.0 %
-1.2 → -1.2 %
#64, stacked on #59, adds FitPolicy.continuumEdgeStep = .broadened as an option. .sharp stays the default and is the earlier form, value for value. Making it the default first needs the kit's registered synthetic generators moved to a convolved continuum: five registered results move, because they plant a sharp step.
Next on this issue:
(a) The default flip, with those re-measurements.
(b) The segment above the edge: the order, or a log-energy variable. Orders (9, 9) take the synthetic Si from -25 % to -8 % but do not help on the Leeds spectrum.
(c) On Leeds, the remaining data excess at 1.56-1.65 keV sits on the high side of the Al K lines. The tied Al K-beta weight (EPQ 0.0132) at the edge is the candidate.
Ice layer on the detector (the O question from #15), measured at no extra cost on the same spectrum. Ice was put on the generic SDD efficiency, broadened by the resolution, and the continuum fitted against it:
The unweighted RSS minimum is at 0.81 µm, with a statistical sigma of 0.08 µm (RSS scaled by chi2_red).
The Pearson minimum is at 0.5-0.6 µm, so the model-choice spread is about ±0.3 µm.
Without ice, the data sit 434 counts above the model in 0.45-0.54 keV. With 0.8 µm ice the excess is 110 counts, but the data then sit 292 counts above the model in 0.56-0.70 keV.
The fitted C K-alpha net moves from 51 to 108-134 counts, so the term is partly confounded with the C line.
What is left above the Al K edge, and making the broadened step the default (#65, stacked on #64)
Real data: Snelson, Collins and MacArthur (2026), Elemental tomography dataset of Mg-Al-Ca alloy, University of Leeds, https://doi.org/10.5518/1826, CC BY 4.0. File Al_Wedge_Standard/Al_EDS-HAADF.emd (Titan G2 200 kV, Super-X): a pool of 214 793 px on the refined axis. Synthetic truth is planted, not measured. All results stay validation: "none".
1. The residual above the edge is the Al K-beta line
Cause: the tied Al K-beta weight. eXSpy's xray_lines.json ties Al Kb at 0.0132 of Ka, at 1.5596 keV. NIST EPQ gives 0.0315.
What would refute it: a free line at the K-beta energy that does not take up the excess, or a χ² minimum somewhere else when the line's energy is scanned. Neither happens.
A free Gaussian scanned from 1.54 to 1.63 keV has its χ²/n minimum at 1.56-1.58 keV (2.34, against 2.92 at either end of the scan). That is the K-beta energy.
The other two candidates:
Incomplete charge collection is refuted. A low-energy tail makes both sides of Al Ka worse.
The extra split works on real data only. It fixes the Leeds wedge numerically, but it fails on synthetic data.
Synthetic Al film generated in the test (3e5 Al Ka, 2000 Si Ka, noise-free, planted Kb 0.0132). Si bias:
variant
11 % step
30 % step
sharp
−15.7 %
−38.7 %
broadened
−11.3 %
−25.4 %
Kb free
−13.8 % (reads Kb 0.011)
−28.0 % (reads Kb 0.011)
Kb tied at EPQ 0.0315
+6.9 %
−6.6 %
split at 1.70 keV
−16.1 %
−32.8 %
tail, f 0.015
−8.9 %
−23.2 %
Demo pools with the default sum peaks, noise-free, blurred generator. Si bias:
pool
broadened
Kb tied at EPQ
split at 1.70 keV
recipe A
−1.3 %
+35.9 %
−0.8 %
matrix map
−1.6 %
+35.9 %
−0.7 %
No change ships for the residual. Each candidate fails on one side:
A tied EPQ weight breaks every synthetic set, because they plant eXSpy's 0.0132.
A free Kb reads 0.011 against a planted 0.0132, so it trades with the continuum.
The split worsens the synthetic film.
Next: a K-beta weight option, measured on a synthetic set that plants the EPQ weight.
The generators now blur their continuum with the detector resolution (tools/edx-sim/detector_blur.py). Its rebuilt continuum matches forward.py to 5e-16. The demo pools are rebuilt from the sim_edx v2.0 truth arrays and checked channel by channel in 9.5-19 keV.
.sharp stays available; it reproduces the old default value for value.
Migration: the default policy JSON gains "continuumEdgeStep":"broadened". A stored policy without the key reads .sharp.
The registered results, re-measured under the new default:
Absorption-truth Si: the pin goes from −6.7 % to −1.67 %.
Weak-line badge (A and S are the two generators), sharp → broadened:
planted Mg (generator)
sharp
broadened
900 (A)
−295
−270 ± 31
882 (S)
−310
−272 ± 23
3000 (A)
−402
−325 ± 38
2899 (S)
−310
−226 ± 22
Realistic-L: the Ti pins move by up to 13 counts.
Registered bar lowered: the proposer's 1 % Mg ×100 cell on the Kramers continuum is now a candidate in 5 of 6 draws, not 6. One draw has no residual peak at Mg.
Gate green, the parity target included. Two numerics reviews were done before the feat! commit. CI is pending.
Activity
Paullo9 commentedon Oct 31, 2026
Diagnosis done locally on the owner's data; the data and every number measured on it stay private. No kit change in this round: no single kit defect with a clear fix was found.
What the experiment separated, in general terms:
eds-absorption-truth.json(no detector Si edge) the same split triples the Si sigma and moves Si by -4 % to +19 % depending on the order, so it is not shipped as a default.FitPolicy.continuumEdges/continuumOrdersalready let a consumer choose it.Next: a physical detector Si-edge term in the continuum (no free polynomial freedom under Si K-alpha), tested on a planted spectrum that has a dead-layer step, then measured on a Si-free standard. All results stay
validation: "none".test: golden baseline re-recorded for continuumDeadLayerMicrons, no n…
Paullo9 commentedon Oct 31, 2026
Checked on the public AlMgSi demo set (
demo-edx, generatorsim_edx.pyv2.0, seed 42, ladder seed 52), which carries planted truth on synthetic data: recipe compositions, the true k, four-segment absorption, a 1.5 % Al K-alpha tail (0.12 keV), Si internal fluorescence, Si escape, sum peaks (parents lose the photons) and stray Cu K. No detector dead layer is planted.Pipeline:
PooledQuantifier.runwith the true k typed, the truth geometry and thickness, absorption on, the true axis locked. Each pool was fitted twice: the Poisson data, and the noise-free expected spectrum x100 (the fit bias without noise). Si planted counts include the Si internal-fluorescence peak (the kit convention).Default fit (exSpy-equivalent: one Gaussian per line, no sum peaks), net against planted, noise-free:
eds-absorption-truth.json(recipe A, 1e4 px)At% on the data: matrix map Mg 0.44 / Si 0.45 against 0.60 / 0.60 truth; L5 Si 0.36 against 0.60.
The Si deficit follows the unmodelled sum peaks, not a dead layer. The Al+Al sum peak (2.97 keV) and the other sum peaks pull the continuum segment above the Al K edge; under least squares that lowers Si K-alpha. The cheap refuting experiment was to switch on
SumEscapeModel(sumPeaks: true)and see whether Si stays biased. It does not: noise-free Si goes from -18.2 % to -4.0 % on the fixture, -16.6 % to -3.9 % on the matrix map, -14.9 % to -3.6 % on recipe A, -57 % to -8 % on L5 and -8.4 % to -1.2 % on L6. Reduced chi2 on the x100 spectra falls from 120-3000 to 0.04-8.The earlier diagnosis on real data placed the Si deficit in the continuum between the Al K edge and 2.2 keV. On synthetic data the deficit follows the sum peaks instead, so the dead layer and a Si-free standard are no longer the next step here.
Dead-layer term (#50). A typed 0 um reproduces the default fit exactly. Fitted on this detector, which has no dead layer, it reads 0.17-0.43 um and moves Si further down in every Al pool: noise-free matrix map from -16.6 % to -23.8 %, L5 from -57 % to -75 %. On the pure beta'' pool it is neutral. The fitted thickness absorbs the sum-peak misfit, so it should be fitted only together with the sum-peak model, or typed.
Absorption correction: right. On L7 the corrected Mg/Si pull is -0.4 and the uncorrected one 5.0.
Next step: the pooled path models sum peaks when the data call for it, keeps the exSpy-equivalent fit as a switch, and pins these demo numbers as regression tests (PR to follow). Results stay
validation: "none": the truth is synthetic.Paullo9 commentedon Oct 31, 2026
The continuum at the Al K edge on a real Si-free spectrum: diagnosis and #64
Data: Snelson, Collins and MacArthur (2026), Elemental tomography dataset of Mg-Al-Ca alloy, University of Leeds, https://doi.org/10.5518/1826, licence CC BY 4.0. File
Al_Wedge_Standard/Al_EDS-HAADF.emd: Titan G2 at 200 kV, Super-X. Pool of 214 793 px, 3e5 Al K-alpha counts, the refined axis from #15.Cause. There are two parts.
What would refute part 1: broadening the step leaves the misfit unchanged. It does not; it halves it.
exSpy 0.3.2 has no edge in its background: it fits a polynomial (order 6) across the whole range. The step is the kit's own design, and no parity path is involved.
The detector dead layer (#50) is not the lever here. The data show no step at 1.839 keV, and the 10 nm Al contact layer of the generic SDD model gives about a 1 % step at the Al edge.
Synthetic check, generated in the test. An Al film whose edge is convolved with the detector, 3e5 Al K-alpha, weak Si K-alpha 2000 counts, noise-free:
The AlMgSi demo (sim_edx.py v2.0, noise-free pools ×100, true axis; planted truth on synthetic data) plants an unbroadened step:
#64, stacked on #59, adds
FitPolicy.continuumEdgeStep = .broadenedas an option..sharpstays the default and is the earlier form, value for value. Making it the default first needs the kit's registered synthetic generators moved to a convolved continuum: five registered results move, because they plant a sharp step.Next on this issue:
Ice layer on the detector (the O question from #15), measured at no extra cost on the same spectrum. Ice was put on the generic SDD efficiency, broadened by the resolution, and the continuum fitted against it:
It is a first number, not a calibration.
Results stay
validation: "none".🤖 Generated with Claude Code
feat: detector Si dead-layer step in the EDX simulator and a planted …
feat: optional detector Si dead-layer term in the EDX continuum (#50)
Paullo9 commentedon Oct 31, 2026
What is left above the Al K edge, and making the broadened step the default (#65, stacked on #64)
Real data: Snelson, Collins and MacArthur (2026), Elemental tomography dataset of Mg-Al-Ca alloy, University of Leeds, https://doi.org/10.5518/1826, CC BY 4.0. File
Al_Wedge_Standard/Al_EDS-HAADF.emd(Titan G2 200 kV, Super-X): a pool of 214 793 px on the refined axis. Synthetic truth is planted, not measured. All results stayvalidation: "none".1. The residual above the edge is the Al K-beta line
Cause: the tied Al K-beta weight. eXSpy's
xray_lines.jsonties Al Kb at 0.0132 of Ka, at 1.5596 keV. NIST EPQ gives 0.0315.What would refute it: a free line at the K-beta energy that does not take up the excess, or a χ² minimum somewhere else when the line's energy is scanned. Neither happens.
Leeds wedge, broadened step unless stated otherwise:
A free Gaussian scanned from 1.54 to 1.63 keV has its χ²/n minimum at 1.56-1.58 keV (2.34, against 2.92 at either end of the scan). That is the K-beta energy.
The other two candidates:
Synthetic Al film generated in the test (3e5 Al Ka, 2000 Si Ka, noise-free, planted Kb 0.0132). Si bias:
Demo pools with the default sum peaks, noise-free, blurred generator. Si bias:
No change ships for the residual. Each candidate fails on one side:
Next: a K-beta weight option, measured on a synthetic set that plants the EPQ weight.
2. The broadened step is the default (#65)
tools/edx-sim/detector_blur.py). Its rebuilt continuum matches forward.py to 5e-16. The demo pools are rebuilt from the sim_edx v2.0 truth arrays and checked channel by channel in 9.5-19 keV..sharpstays available; it reproduces the old default value for value."continuumEdgeStep":"broadened". A stored policy without the key reads.sharp.Leeds wedge, before and after:
Demo pools (blurred continuum, noise-free, default sum peaks), sharp → broadened:
The registered results, re-measured under the new default:
Absorption-truth Si: the pin goes from −6.7 % to −1.67 %.
Weak-line badge (A and S are the two generators), sharp → broadened:
Realistic-L: the Ti pins move by up to 13 counts.
Registered bar lowered: the proposer's 1 % Mg ×100 cell on the Kramers continuum is now a candidate in 5 of 6 draws, not 6. One draw has no residual peak at Mg.
Gate green, the parity target included. Two numerics reviews were done before the
feat!commit. CI is pending.🤖 Generated with Claude Code