Coverage for /Users/Newville/Codes/xraylarch/larch/xrd/xrd_tools.py: 26%

80 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-09 10:08 -0600

1#!/usr/bin/env python 

2''' 

3Diffraction functions require for fitting and analyzing data. 

4 

5mkak 2017.02.06 (originally written spring 2016) 

6''' 

7 

8########################################################################## 

9# IMPORT PYTHON PACKAGES 

10 

11import math 

12import numpy as np 

13from numpy import cos, sin, arcsin, degrees 

14from ..utils.physical_constants import PLANCK_HC, TAU, DEG2RAD, RAD2DEG 

15 

16import re 

17import os 

18import cmath 

19 

20########################################################################## 

21# FUNCTIONS 

22 

23def d_from_q(q): 

24 ''' 

25 Converts q axis into d (returned units inverse of provided units) 

26 d = 2*PI/q 

27 ''' 

28 return TAU/q 

29 

30def d_from_twth(twth,wavelength,ang_units='degrees'): 

31 ''' 

32 Converts 2th axis into d (returned units same as wavelength units) 

33 d = lambda/[2*sin(2th/2)] 

34 

35 ang_unit : default in degrees; will convert from 'rad' if given 

36 ''' 

37 if not ang_units.startswith('rad'): 

38 twth = DEG2RAD*twth 

39 return wavelength/(2*sin(twth/2.)) 

40 

41 

42def twth_from_d(d,wavelength,ang_units='degrees'): 

43 ''' 

44 Converts d axis into 2th (d and wavelength must be in same units) 

45 2th = 2*sin^-1(lambda/[2*d]) 

46 

47 ang_unit : default in degrees; will convert to 'rad' if given 

48 ''' 

49 twth = 2*arcsin(wavelength/(2.*d)) 

50 if ang_units.startswith('rad'): 

51 return twth 

52 else: 

53 return RAD2DEG*twth 

54 

55 

56def twth_from_q(q,wavelength,ang_units='degrees'): 

57 ''' 

58 Converts q axis into 2th (q and wavelength will have inverse units) 

59 2th = 2*sin^-1(lambda/[2*d]) 

60 

61 ang_unit : default in degrees; will convert to 'rad' if given 

62 ''' 

63 twth = 2*arcsin((q*wavelength)/(2*TAU)) 

64 if ang_units.startswith('rad'): 

65 return twth 

66 else: 

67 return RAD2DEG*twth 

68 

69def q_from_d(d): 

70 ''' 

71 Converts d axis into q (returned units inverse of provided units) 

72 q = 2*PI/d 

73 ''' 

74 return TAU/d 

75 

76 

77def q_from_twth(twth, wavelength, ang_units='degrees'): 

78 ''' 

79 Converts 2th axis into q (q returned in inverse units of wavelength) 

80 q = [(4*PI)/lamda]*sin(2th/2) 

81 

82 ang_unit : default in degrees; will convert from 'rad' if given 

83 ''' 

84 if not ang_units.startswith('rad'): 

85 twth = DEG2RAD*twth 

86 return ((2*TAU)/wavelength)*sin(twth/2.) 

87 

88def qv_from_hkl(hklall, a, b, c, alpha, beta, gamma): 

89 

90 qv = np.zeros(np.shape(hklall)) 

91 uvol = unit_cell_volume(a,b,c,alpha,beta,gamma) 

92 alpha, beta, gamma = DEG2RAD*alpha, DEG2RAD*beta, DEG2RAD*gamma 

93 q0 = [(b*c*sin(alpha))/uvol,(c*a*sin(beta))/uvol,(a*b*sin(gamma))/uvol] 

94 

95 for i, hkl in enumerate(hklall): 

96 qv[i] = [TAU*hkl[0]*q0[0], TAU*hkl[1]*q0[1], TAU*hkl[2]*q0[2]] 

97 return qv 

98 

99def d_from_hkl(hkl, a, b, c, alpha, beta, gamma, **kws): 

100 h, k, l = hkl[:, 0], hkl[:, 1], hkl[:, 2] 

101 alpha, beta, gamma = DEG2RAD*alpha, DEG2RAD*beta, DEG2RAD*gamma 

102 cos_a, cos_b, cos_g = cos(alpha), cos(beta), cos(gamma) 

103 x = 1-cos_a**2 - cos_b**2 - cos_g**2 + 2*cos_a*cos_b*cos_g 

104 y = ((h*sin(alpha)/a)**2 + 2*k*l*(cos_b*cos_g-cos_a)/(b*c) + 

105 (k*sin(beta)/b)**2 + 2*l*h*(cos_g*cos_a-cos_b)/(c*a) + 

106 (l*sin(gamma)/c)**2 + 2*h*k*(cos_a*cos_b-cos_g)/(a*b)) 

107 d = np.sqrt(x/y) 

108 return d 

109 

110def d_from_hkl_orig(hklall, a, b, c, alpha, beta, gamma): 

111 d = np.zeros(len(hklall)) 

112 alpha, beta, gamma = DEG2RAD*alpha, DEG2RAD*beta, DEG2RAD*gamma 

113 for i,hkl in enumerate(hklall): 

114 h,k,l = hkl 

115 x = 1-cos(alpha)**2 - cos(beta)**2 - cos(gamma)**2 \ 

116 + 2*cos(alpha)*cos(beta)*cos(gamma) 

117 y = (h*sin(alpha)/a)**2 + 2*k*l*(cos(beta)*cos(gamma)-cos(alpha))/(b*c) \ 

118 + (k*sin(beta)/b)**2 + 2*l*h*(cos(gamma)*cos(alpha)-cos(beta))/(c*a) \ 

119 + (l*sin(gamma)/c)**2 + 2*h*k*(cos(alpha)*cos(beta)-cos(gamma))/(a*b) 

120 d[i] = np.sqrt(x/y) 

121 return d 

122 

123def unit_cell_volume(a, b, c, alpha, beta, gamma): 

124 alpha, beta, gamma = DEG2RAD*alpha, DEG2RAD*beta, DEG2RAD*gamma 

125 return a*b*c*(1-cos(alpha)**2-cos(beta)**2-cos(gamma)**2+ 

126 2*cos(alpha)*cos(beta)*cos(gamma))**0.5 

127 

128 

129def E_from_lambda(wavelength, E_units='keV', lambda_units='A'): 

130 ''' 

131 Converts lambda into energy 

132 E = hf ; E = hc/lambda 

133 

134 E_units : default keV; can convert to 'eV' if given 

135 lambda_units : default 'A'; can convert from 'm' or 'nm' if given 

136 ''' 

137 if lambda_units == 'm': 

138 wavelength = wavelength*1e10 

139 elif lambda_units == 'nm': 

140 wavelength = wavelength*10 

141 if E_units.lower() == 'kev': 

142 return PLANCK_HC/wavelength*1e-3 # keV 

143 else: 

144 return (PLANCK_HC/wavelength) # eV 

145 

146 

147def lambda_from_E(E, E_units='keV', lambda_units='A'): 

148 ''' 

149 Converts lambda into energy 

150 E = hf ; E = hc/lambda 

151 

152 E_units : default keV; can convert from 'eV' if given 

153 lambda_units : default 'A'; can convert to 'm' or 'nm' if given 

154 ''' 

155 if E_units.lower() != 'kev': 

156 E = E*1e-3 # keV 

157 scale = 1.e-3 

158 if lambda_units == 'm': 

159 scale = 1.e-13 

160 elif lambda_units == 'nm': 

161 scale = 1e-4 

162 return scale*PLANCK_HC/E 

163 

164def generate_hkl(hmax=15, kmax=15, lmax=15, positive_only=True): 

165 if positive_only: 

166 hklall = np.mgrid[0:hmax+1, 0:kmax+1, 0:lmax+1].reshape(3, -1).T 

167 else: 

168 hklall = np.mgrid[-hmax:hmax+1, -kmax:kmax+1, -lmax:lmax+1].reshape(3, -1).T 

169 return np.array([hkl for hkl in hklall if hkl[0]**2 + hkl[1]**2 + hkl[2]**2 > 0])