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

1import numpy as np 

2 

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 

7 

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. 

13 

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] 

25 

26 Additional keywords will be passed to pre_edge(), which will be used 

27 to ensure consistent normalization. 

28 

29 Returns 

30 -------- 

31 None, writes `mu_corr` and `norm_corr` (normalized `mu_corr`) 

32 to output group. 

33 

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 

54 

55 # generate normalized mu for correction 

56 preinp = preedge(energy, mu, **pre_opts) 

57 

58 ang_corr = (np.sin(max(1.e-7, np.deg2rad(anginp))) / 

59 np.sin(max(1.e-7, np.deg2rad(angout)))) 

60 

61 # find edge energies and fluorescence line energy 

62 e_edge = xray_edge(elem, edge).energy 

63 e_fluor = xray_line(elem, line).energy 

64 

65 # calculate mu(E) for fluorescence energy, above, below edge 

66 

67 muvals = material_mu(formula, np.array([e_fluor, e_edge-10.0, 

68 e_edge+10.0]), density=1) 

69 

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']