Coverage for larch/math/lineshapes.py: 48%

33 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-10-16 21:04 +0000

1#!/usr/bin/env python 

2""" 

3Some common lineshapes and distribution functions 

4""" 

5 

6from __future__ import division 

7 

8from numpy import exp, pi, sqrt, where 

9 

10from scipy.special import erfc as sp_erfc 

11from scipy.special import wofz as sp_wofz 

12from scipy.special import erf as sp_erf 

13from scipy.special import gamma as sp_gamma 

14from scipy.special import gammaln as sp_gammaln 

15 

16from lmfit.lineshapes import (gaussian, lorentzian, voigt, pvoigt, moffat, 

17 pearson7, breit_wigner, damped_oscillator, 

18 dho, logistic, lognormal, students_t, 

19 doniach, skewed_gaussian, expgaussian, 

20 skewed_voigt, step, rectangle, exponential, 

21 powerlaw, linear, parabolic) 

22 

23stau = sqrt(2*pi) 

24s2 = sqrt(2.0) 

25 

26def hypermet(x, amplitude=1.0, center=0., sigma=1.0, 

27 step=0.1, tail=0.1, beta=0.5, gamma=0.01): 

28 """ 

29 hypermet function to simulate XRF peaks and/or Compton Scatter Peak, 

30 slightly modified. 

31 

32 Arguments 

33 --------- 

34 x array of ordinate (energy) values 

35 amplitude overall scale factor 

36 center peak centroid 

37 sigma peak width parameter sigma 

38 step heigh of low-x erfc step function [0.1] 

39 tail height of tail function [0.1] 

40 beta slope of tail function [0.5] 

41 gamma gamma value for Voigt lineshape [0.01] 

42 

43 

44 Notes 

45 ----- 

46 The function is given by (with some error checking for 

47 small values of sigma, beta, and gamma, and with 

48 s2 = sqrt(2) and stau = sqrt(2*pi)): 

49 

50 arg = (x - center)/sigma 

51 if use_voigt: 

52 peak = wofz(arg+1j*gamma).real 

53 else: 

54 peak = exp(-arg**2 /2) 

55 

56 stepfunc = step * erfc(arg/2.0) / 200.0 

57 tailfunc = tail * exp(arg/beta) * erfc(arg/s2 + 1.0/beta)) 

58 hypermet = amplitude * (peak + stepfunc + tailfunc) / (2.0*stau*sigma) 

59 

60 This follows (for Gaussian lineshape) the definitions given in 

61 ED-XRF SPECTRUM EVALUATION AND QUANTITATIVE ANALYSIS 

62 USING MULTIVARIATE AND NONLINEAR TECHNIQUES 

63 P. Van Espen, P. Lemberge 

64 JCPDS-International Centre for Diffraction Data 2000, 

65 Advances in X-ray Analysis,Vol.43 560 

66 

67 But is modified to prefer Voigt of Gaussian (as Lorentzian-like tails on the 

68 positive energy side of a peak are common), and to better preserve area with 

69 changing values of tail and beta. 

70 

71 """ 

72 sigma = max(1.e-15, sigma) 

73 beta = max(1.e-15, beta)*s2 

74 gamma = max(1.e-15, gamma)/s2 

75 step = step/100.0 

76 

77 arg = (x - center)/(s2*sigma) 

78 arg[where(arg>700)] = 700.0 

79 

80 peakfunc = sp_wofz((arg + 1j*gamma) ).real 

81 

82 stepfunc = step*sp_erfc(arg)/(2*sp_wofz(1j*gamma).real) 

83 

84 arg[where(arg>beta*350)] = beta*350.0 

85 tailfunc = sp_erfc(arg + 1./beta)*exp(2*arg/beta) 

86 tailfunc *= 2*tail/(beta*exp(-1.0/beta**2)) 

87 

88 return amplitude*(peakfunc + stepfunc + tailfunc)/(stau*sigma) 

89 

90def erf(x): 

91 """Return the error function. 

92 erf = 2/sqrt(pi)*integral(exp(-t**2), t=[0, z]) 

93 """ 

94 return sp_erf(x) 

95 

96def erfc(x): 

97 """Return the complementary error function. 

98 erfc = 1 - erf(x) 

99 """ 

100 return sp_erfc(x) 

101 

102def wofz(x): 

103 """Return the fadeeva function for complex argument. 

104 wofz = exp(-x**2)*erfc(-i*x) 

105 """ 

106 return sp_wofz(x) 

107 

108def gamma(x): 

109 """Return the gamma function.""" 

110 return sp_gamma(x) 

111 

112def gammaln(x): 

113 """Return the log of absolute value of gamma function.""" 

114 return sp_gammaln(x)