Coverage for larch/xafs/fluo.py: 23%
30 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
« prev ^ index » next coverage.py v7.6.0, created at 2024-10-16 21:04 +0000
1import numpy as np
3from xraydb import xray_line, xray_edge, material_mu
4from larch import parse_group_args, Make_CallArgs
5from .xafsutils import set_xafsGroup
6from .pre_edge import preedge
8@Make_CallArgs(["energy","mu"])
9def fluo_corr(energy, mu, formula, elem, group=None, edge='K', line='Ka', anginp=45,
10 angout=45, _larch=None, **pre_kws):
11 """correct over-absorption (self-absorption) for fluorescene XAFS
12 using the FLUO alogrithm of D. Haskel.
14 Arguments
15 ---------
16 energy array of energies
17 mu uncorrected fluorescence mu
18 formula string for sample stoichiometry
19 elem atomic symbol or Z of absorbing element
20 group output group [default None]
21 edge name of edge ('K', 'L3', ...) [default 'K']
22 line name of line ('K', 'Ka', 'La', ...) [default 'Ka']
23 anginp input angle in degrees [default 45]
24 angout output angle in degrees [default 45]
26 Additional keywords will be passed to pre_edge(), which will be used
27 to ensure consistent normalization.
29 Returns
30 --------
31 None, writes `mu_corr` and `norm_corr` (normalized `mu_corr`)
32 to output group.
34 Notes
35 -----
36 Support First Argument Group convention, requiring group
37 members 'energy' and 'mu'
38 """
39 energy, mu, group = parse_group_args(energy, members=('energy', 'mu'),
40 defaults=(mu,), group=group,
41 fcn_name='fluo_corr')
42 # gather pre-edge options
43 pre_opts = {'e0': None, 'nnorm': 1, 'nvict': 0,
44 'pre1': None, 'pre2': -30,
45 'norm1': 100, 'norm2': None}
46 if hasattr(group, 'pre_edge_details'):
47 uopts = getattr(group.pre_edge_details, 'call_args', {})
48 for attr in pre_opts:
49 if attr in uopts:
50 pre_opts[attr] = uopts[attr]
51 pre_opts.update(pre_kws)
52 pre_opts['step'] = None
53 pre_opts['nvict'] = 0
55 # generate normalized mu for correction
56 preinp = preedge(energy, mu, **pre_opts)
58 ang_corr = (np.sin(max(1.e-7, np.deg2rad(anginp))) /
59 np.sin(max(1.e-7, np.deg2rad(angout))))
61 # find edge energies and fluorescence line energy
62 e_edge = xray_edge(elem, edge).energy
63 e_fluor = xray_line(elem, line).energy
65 # calculate mu(E) for fluorescence energy, above, below edge
67 muvals = material_mu(formula, np.array([e_fluor, e_edge-10.0,
68 e_edge+10.0]), density=1)
70 alpha = (muvals[0]*ang_corr + muvals[1])/(muvals[2] - muvals[1])
71 mu_corr = mu*alpha/(alpha + 1 - preinp['norm'])
72 preout = preedge(energy, mu_corr, **pre_opts)
73 if group is not None:
74 if _larch is not None:
75 group = set_xafsGroup(group, _larch=_larch)
76 group.mu_corr = mu_corr
77 group.norm_corr = preout['norm']