Skip to content

Detector Al K-alpha tail calibration for Mg in a dilute Al matrix #60

Open

Description

@Paullo9

Problem

In a dilute Al matrix, Mg K-alpha (1.254 keV) sits on the low-energy tail of Al K-alpha (1.487 keV). The default pooled fit models every line as a pure Gaussian, so the tail counts are not attributed to Al and the Mg net is wrong.

All numbers below are from the public synthetic AlMgSi demo set (mac4DSTEM demo-edx, generator sim_edx.py v2.0, seed 42). The truth is planted in the simulation (Al K-alpha tail 1.5 %, slope 0.12 keV; matrix Mg 0.6 at%), not a measurement, so these results stay validation: "none".

What was measured

  • The tail cannot be fitted together with the sum peaks on pooled spectra. With LineTail free next to the sum-peak model (feat!: the pooled fit models sum peaks when the strongest line's self pair is significant #59), the fitted tail fraction reads 0 to one third of the planted 1.5 %, and Mg K-alpha stays 22 to 45 % low (L5 -22 %, M_A -32 %, M_matrix -45 %, noise-free).
  • A tail measured once and typed in works. TailEstimate on a high-count spectrum gives fraction 0.0095, slope 0.073 keV. Typed into FitPolicy.lineTail with the sum peaks on, Mg K-alpha reads +3.2 % (L5) and +2.6 % (M_A) against planted.
  • M_matrix is still -14.7 % with the typed tail. This is not explained. M_matrix pools seven matrix recipes and thicknesses (2 897 px); the cause has not been isolated.

Wanted

  1. A calibration workflow: measure the Al K-alpha tail once per detector (TailEstimate on a high-count Al-rich spectrum), store it with the detector, and apply it to pooled fits through FitPolicy.lineTail. The footer names the stored calibration and its source.
  2. The M_matrix residual diagnosed: state the cause and what would refute it, then run the cheap experiment (for example, one recipe and one thickness at a time, or the planted tail typed instead of the estimate).
  3. A real-data check of the tail: a pure Al spectrum from a public dataset with the same detector as an Al-alloy spectrum.

Related: #8, #15, #59 (sum peaks in the pooled fit).

🤖 Generated with Claude Code

Activity

  1. Paullo9 commented on Oct 31, 2026

    @Paullo9
    ContributorAuthor

    Real-data check of the Al K-alpha tail on a pure Al standard.

    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: FEI Titan G2 80-200 at 200 kV, Super-X (four SDDs, elevation 18 deg, tilt 0), 138 x 2048 px, 754 frames. Truth: pure Al.

    Reader. FormatoKit 0.11.0 VeloxEMDReader reads it. The pooled spectrum equals the four per-detector sum spectra stored in the file, count for count (181 137 777 counts; 321 872 in 1.35-1.65 keV). There is no reader gap.

    Pool. 214 793 px with at least one count in 0.3-10 keV, holding 3.0e5 Al K-alpha counts. Fit: PooledQuantifier.run at the PR #59 head (bce80a3, which contains main e0d9fed), Al quantified, C O Fe Cu Ga fit only. Axis refined: +2.3 eV, +0.10 %, R 128.3 eV. chi2_red 2.03.

    TailEstimate on the same refined axis

    range fraction slope residual norm
    0.2-20 keV (default) 0.0158 1.00 keV, the upper edge of the search 1042.9 to 1042.3 (-0.06 %)
    0.2-2.6 keV 0 - unchanged
    0.8-2.6 keV 0 - unchanged

    The default-range result is a broad shelf on the search's edge, not a line tail: it improves the residual by 0.06 %. On the ranges around the line, no tail is found.

    The demo's slope, fixed at 0.12 keV, on 0.8-2.6 keV (sum of (data - model)^2 / data):

    fraction 0 0.25 % 0.5 % 1.0 % 1.5 %
    chi2 1510.7 1514.8 1520.3 1528.4 1521.9

    The minimum is at 0. The demo's planted 1.5 % costs delta chi2 11, or 3.6 after scaling by that range's chi2_red of 3.1. Without a tail, the low-side residual (1.0-1.42 keV) is +121 counts, which is 0.04 % of Al K-alpha.

    Against the synthetic demo (planted 1.5 %, 0.12 keV; TailEstimate on the demo read 0.95 %, 0.073 keV): this real Super-X shows no measurable Al K-alpha tail. Best estimate 0, with an upper bound of roughly 0.5 % at 0.12 keV slope. The demo's tail is at least 3x larger than this detector's. That does not settle other detectors: a pure Al spectrum from each detector is still the calibration step. What would refute this result: a tail found on a pure Al pool with many more counts from the same detector type.

    Effect on Mg. On the MgO standard of the same archive (see #15), a typed tail moves Mg by at most 0.03 at%, whether it is this measurement (0.0158 / 1.0 keV) or the demo's 1.5 % / 0.12 keV. The tail matters for a weak line beside a strong one (Mg in an Al matrix), not for MgO.

    Small suggestion. When the best slope sits on the search's edge, the source string could say so, as it already does for fraction 0.

    What does dominate the residual is the continuum at the Al K edge, not the line shape. The model drops by 770 counts between the channels at 1.559 and 1.564 keV, where the data are smooth. The data are above the model by 1 700 counts in 1.53-1.65 keV and below it by 2 511 counts (39 %) in 1.65-2.2 keV, on a spectrum with no Si. Details are on #15.

    Results stay validation: "none": one standard, one detector.

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions