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
« 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.
5mkak 2017.02.06 (originally written spring 2016)
6'''
8##########################################################################
9# IMPORT PYTHON PACKAGES
11import math
12import numpy as np
13from numpy import cos, sin, arcsin, degrees
14from ..utils.physical_constants import PLANCK_HC, TAU, DEG2RAD, RAD2DEG
16import re
17import os
18import cmath
20##########################################################################
21# FUNCTIONS
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
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)]
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.))
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])
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
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])
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
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
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)
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.)
88def qv_from_hkl(hklall, a, b, c, alpha, beta, gamma):
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]
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
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
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
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
129def E_from_lambda(wavelength, E_units='keV', lambda_units='A'):
130 '''
131 Converts lambda into energy
132 E = hf ; E = hc/lambda
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
147def lambda_from_E(E, E_units='keV', lambda_units='A'):
148 '''
149 Converts lambda into energy
150 E = hf ; E = hc/lambda
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
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])