From 11448b7b31039d6ac121255445d47b66010ee389 Mon Sep 17 00:00:00 2001 From: jhuang165 Date: Thu, 1 Oct 2026 23:26:56 -0500 Subject: [PATCH] fluo_corr: normalize with the group's pre_edge ranges fluo_corr looked for the group's normalization in pre_edge_details.call_args, which pre_edge never sets, so it always used its own defaults (norm1=100, nnorm=1) and re-found E0 on the corrected spectrum. On a short XANES scan norm1=100 is past the last point, and norm_corr is not comparable with norm. Use the ranges pre_edge stored in pre_edge_details, and the group's e0. --- larch/xafs/fluo.py | 14 +++++++++----- tests/test_xafs_fluo.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 tests/test_xafs_fluo.py diff --git a/larch/xafs/fluo.py b/larch/xafs/fluo.py index c96f57fa8..76266e7ae 100644 --- a/larch/xafs/fluo.py +++ b/larch/xafs/fluo.py @@ -43,11 +43,15 @@ def fluo_corr(energy, mu, formula, elem, group=None, edge='K', line='Ka', anginp pre_opts = {'e0': None, 'nnorm': 1, 'nvict': 0, 'pre1': None, 'pre2': -30, 'norm1': 100, 'norm2': None} - if hasattr(group, 'pre_edge_details'): - uopts = getattr(group.pre_edge_details, 'call_args', {}) - for attr in pre_opts: - if attr in uopts: - pre_opts[attr] = uopts[attr] + # use the ranges pre_edge() settled on for this group, so that + # norm_corr is normalized the same way as norm + details = getattr(group, 'pre_edge_details', None) + if details is not None: + for attr in ('pre1', 'pre2', 'norm1', 'norm2', 'nnorm'): + if getattr(details, attr, None) is not None: + pre_opts[attr] = getattr(details, attr) + if getattr(group, 'e0', None) is not None: + pre_opts['e0'] = group.e0 pre_opts.update(pre_kws) pre_opts['step'] = None pre_opts['nvict'] = 0 diff --git a/tests/test_xafs_fluo.py b/tests/test_xafs_fluo.py new file mode 100644 index 000000000..11537595b --- /dev/null +++ b/tests/test_xafs_fluo.py @@ -0,0 +1,29 @@ +from pathlib import Path + +import numpy as np +import pytest + +from larch.io import read_ascii +from larch.xafs import fluo_corr, pre_edge + +basedir = Path(__file__).parent.parent.resolve() + + +@pytest.mark.parametrize('pre_edge_opts', [ + {}, + dict(pre1=-100, pre2=-30, norm1=50, norm2=300, nnorm=2), +]) +def test_fluo_corr_uses_group_normalization(pre_edge_opts): + """fluo_corr() normalizes with the ranges pre_edge() used for the group""" + dat = read_ascii(Path(basedir, 'examples', 'xafsdata', 'fe2o3_rt1.xmu')) + pre_edge(dat, **pre_edge_opts) + details = dat.pre_edge_details + explicit = {attr: getattr(details, attr) + for attr in ('pre1', 'pre2', 'norm1', 'norm2', 'nnorm')} + + fluo_corr(dat.energy, dat.mu, 'Fe2O3', 'Fe', group=dat, e0=dat.e0, **explicit) + explicit_mu, explicit_norm = dat.mu_corr.copy(), dat.norm_corr.copy() + + fluo_corr(dat.energy, dat.mu, 'Fe2O3', 'Fe', group=dat) + np.testing.assert_allclose(dat.mu_corr, explicit_mu) + np.testing.assert_allclose(dat.norm_corr, explicit_norm)