| |
- Bmatrix(basis_vectors)
- Calculate the Busing and Levy B matrix from real space basis vectors, with units of 2pi
"choose the x-axis parallel to a*, the y-axis in the plane of a* and b*, and the z-axis perpendicular to that plane"
From: W. R. Busing and H. A. Levy, Acta Cryst. (1967). 22, 457-464
"Angle calculations for 3- and 4-circle X-ray and neutron diffractometers"
See also: https://docs.mantidproject.org/nightly/concepts/Lattice.html
B = [[b1, b2 * cos(beta3), b3 * cos(beta2)],
[0, b2 * sin(beta3), -b3 * sin(beta2) * cos(alpha1)],
[0, 0, 1 / a3]]
return 2pi * B # equivalent to transpose([a*, b*, c*])
:param basis_vectors: [3*3] array of basis vectors [a[3], b[3], c[3]]
:return: [3*3] B matrix * 2 pi
- Q2hkl(qvec, UVstar)
- Index vectors in an orthonal basis with a reciprocal basis
:param qvec: [nx3] array of coordinates in an orthogonal basis in A-1
:param UV: [3x3] array of unit cell vectors [[a1,a2,a3],[b1,b2,b3],[c1,c2,c3]]
:return: [nx3] array of vectors in reciprocal lattice units
- RcSp(UV)
- Generate reciprocal cell from real space unit vecors
Usage:
UVs = RcSp(UV)
UV = [[3x3]] matrix of vectors [a,b,c]
- UV2latpar(UV)
- Convert UV=[a,b,c] to a,b,c,alpha,beta,gamma
a,b,c,alpha,beta,gamma = UV2latpar(UV)
- arrange_atom_order(list_of_elements)
- Arrange a list of elements in the correct chemical order
['Li','Co','O'] = arrange_atom_order(['Co', 'O', 'Li'])
:param list_of_elements: [list of str]
:return: [list of str]
- atom_properties(elements=None, fields=None)
- Loads the atomic properties of a particular atom from a database
Atomic properties, scattering lengths, form factors and absorption edges for elements upto and including Uranium.
Values are taken from various online sources, see data/README.md for more details.
Usage:
A = atom_properties() >> returns structured array of all properties for all atoms A[0]['Element']='H'
A = atom_properties('Co') >> returns structured array of all properties for 1 element
B = atom_properties('Co','Weight') >> returns regular 1x1 array
B = atom_properties(['Co','O'],'Weight') >> retruns regular 2x1 array
A = atom_properties('Co',['a1','b1','a2','b2','a3','b3','a4','b4','c']) >> returns structured array of requested properties
A = atom_properties(['Co','O'],['Z','Weight']) >> returns 2x2 structured array
Available properties:
A = atom_properties()
print(A.dtype.names)
print(a[25]['Element'])
>> 'Fe'
Available information includes:
Z = Element number
Element = Element symbol
Name = Element name
Group = Element Group on periodic table
Period = Element period on periodic table
Block = Element electronic block (s,p,d,f)
ValenceE = Number of valence electrons
Config = Element electronic orbital configuration
Radii = Atomic Radii (pm)
Weight = Standard atomic weight (g)
Coh_b = Bound coherent neutron scattering length
Inc_b = Bound incoherent neutron scattering length
Nabs = Neutron absorption coefficient
Nscat = Neutron scattering coefficient
a1 = Electron form factor
b1 = Electron form factor
a2 = Electron form factor
b2 = Electron form factor
a3 = Electron form factor
b3 = Electron form factor
a4 = Electron form factor
b4 = Electron form factor
c = Electron form factor
j0_A = Magnetic Form factor
j0_a = Magnetic Form factor
j0_B = Magnetic Form factor
j0_b = Magnetic Form factor
j0_C = Magnetic Form factor
j0_c = Magnetic Form factor
j0_D = Magnetic Form factor
K = x-ray absorption edge
L1 = x-ray absorption edge
L2 = x-ray absorption edge
L3 = x-ray absorption edge
M1... = x-ray absorption edge
- atomic_scattering_factor(element, energy_kev=None)
- Read atomic scattering factor table, giving f1+f2 for different energies
From: http://henke.lbl.gov/optical_constants/asf.html
:param element: str or list of str, name of element. If element string includes a number, this will multiply values
:param energy_kev: float or list energy in keV (None to return original, uninterpolated list)
:return: f1, f2, shape dependent on shapes of element and energy_kev: float, or [ene] or [ele, ene]
- attenuation(element_z, energy_kev)
- Returns the x-ray mass attenuation, u/p, in cm^2/g
e.g. A = attenuation(23,np.arange(7,8,0.01)) # Cu
A = attenuation([23,24,25], 5.6)
a = attenuation(19,4.5) # K
- balance_atom_charge(list_of_elements, occupancy=None)
- Determine the default charges and assign remaining charge to
unspecified elements
:param list_of_elements: list of element symbols ['Co', 'Fe', ...]
:param occupancy: None or list of occupancies, same length as above
:return: [list of charges]
- biso2uiso(biso)
- Convert B isotropic thermal parameters to U isotropic thermal parameters
:param biso: Biso value or array
:return: Uiso value or array
- cal2theta(qmag, energy_kev=17.794, wavelength_a=None)
- Calculate scattering angle at particular energy in keV from magnitude of the wavevector, |Q|
twotheta = cal2theta(Qmag, energy_kev=17.794)
- equivalent to -
twotheta = 2 * arcsin( qmag * wl / 4pi )
:param qmag: float or array of wavevector magnitudes, in inverse-Angstroms
:param energy_kev: float photon energy in keV
:param wavelength_a: float wavelength in Anstrom
:return two-theta angle in degrees (or array if qmag is array)
- calc_vol(UV)
- Calculate volume in Angstrom^3 from unit vectors
- caldspace(twotheta, energy_kev=17.794, wavelength_a=None)
- Calculate d-spacing from two-theta
dspace = caldspace(tth, energy_kev)
- equivalent to -
dspace = wl / (2 * sin(theta))
:param twotheta: float or array of scattering angles, in degrees
:param energy_kev: float photon energy in keV
:param wavelength_a: float wavelength in Anstrom
:return lattice d-spacing in Anstrom
- callattice(twotheta, energy_kev=17.794, hkl=(1, 0, 0))
- Calculate cubic lattice parameter, a from reflection two-theta
:param twotheta: Bragg angle, deg
:param energy_kev: energy in keV
:param hkl: reflection (cubic only
:return: float, lattice contant
- calqmag(twotheta, energy_kev=17.794, wavelength_a=None)
- Calculate |Q| at a particular 2-theta (deg) for energy in keV
magQ = calqmag(twotheta, energy_kev=17.794)
- equivalent to -
qmag = 4 * pi * sin(theta) / wl
:param twotheta: float or array of scattering angles, in degrees
:param energy_kev: float photon energy in keV
:param wavelength_a: float wavelength in Anstrom
:return wavevector magnitude in inverse-Angstrom
- cif2dict(cifvals)
- From a dict of key:value pairs generated from a *.cif file (using readcif),
read standard crystallographic infromation into a crystal dictionary, with keys:
'filename' - cif filename
'name' - name of structure
'unit vector' - [3x3] array of basis vectors [a,b,c]
'parent cell' - [3x3] array of parent basis vectors [a,b,c]
'symmetry' - list of string symmetry operations
'space group' - Space Group string
'space group number' - Space group number
'cif' - cif dict
The following are specific to atomis within the unit cell:
'atom type' - list of elements e.g. ['Co','O', 'O']
'atom label' - list of atom site names e.g. ['Co1, 'O1', 'O2']
'atom position' - [nx3] array of atomic positions
'atom occupancy'- [nx1] array of atom site occupancies
'atom uiso' - [nx1] array of atom site isotropic thermal parameters
'atom uaniso' - [nx6] array of atom site anisotropic thermal parameters
'mag moment' - [nx3] array of atom site magnetic moment vectors
'mag time' - [nx3] array of atom site magnetic time symmetry
'misc'] = [element, label, cif_pos, occ, Uiso]
:param cifvals: dict from readcif
:return: dict
- cif2table(cif)
- Generate Latex table of atomic positions from cif dictionary
:param cif: cif dict from readcif
:return: str
- cif_check(cifvals, required_keys=None, bad_value='?')
- Returns True if all basic required cif parameter are available and real.
E.G.:
cifvals = readcif(file.cif)
if cif_check(cifvals):
print('File OK')
:param cifvals: dict of cif keys form readcif
:param required_keys: list of key strings, or None for default
:param bad_value: if this value is in the cif key item, return False
:return: bool
- cif_symmetry(cifvals)
- Read symmetries from a cif dict
:param cifvals:
:return: list(symmetry_operations), list(magnetic_operations), list(time operations)
- count_atoms(list_of_elements, occupancy=None, divideby=1, latex=False)
- Count atoms in a list of elements, returning condenced list of elements
:param list_of_elements: list of element symbols
:param occupancy: list of occupancies of each element (default=None)
:param divideby: divide each count by this (default=1)
:param latex: False*/True
:return: [list of str]
- count_charges(list_of_elements, occupancy=None, divideby=1, latex=False)
- Count atoms in a list of elements, returning condenced list of elements with charges
:param list_of_elements: list of element symbols
:param occupancy: list of occupancies of each element (default=None)
:param divideby: divide each count by this (default=1)
:param latex: False*/True
:return: [list of str]
- cut2powder(qx, qy, qz, cut)
- Convert 2D reciprocal space cut to powder pattern
:param qx: [n,m] array of Q coordinates in x
:param qy: [n,m] array of Q coordinates in y
:param qz: [n,m] array or float of Q coordinates in z
:param cut: [n,m] array of intensities
:return: qm[o], pow[o]
- debroglie_energy(wavelength_a, mass_kg)
- Calcualte the energy in electronvolts using DeBroglie's formula
E [keV] = h^2 / (2 * e * mass [kg] * A^2 * lambda^2 [A] * 1e3)
:param wavelength_a: wavelength in Angstroms
:param mass_kg: mass in kg
:return: energy in keV
- debroglie_wavelength(energy_kev, mass_kg)
- Calcualte the wavelength in Angstroms using DeBroglie's formula
lambda [A] = h / sqrt( 2 * mass [kg] * E [keV] * 1e3 * e )
:param energy_kev: energy in keV
:param mass_kg: mass in kg
:return: wavelength in Anstroms
- debyewaller(uiso, Qmag=0)
- Calculate the debye waller factor for a particular Q
T = debyewaller(uiso,Qmag=[0])
T = exp( -2*pi^2*Uiso/d^2 )
T = exp( -Uiso/2 * Q^2 )
- default_atom_charge(element)
- Returns the default charge value for the element
:param element: str: 'Fe'
:return: int or nan
- detector_angle_size(detector_distance_mm=565, height_mm=67, width_mm=34, pixel_size_um=172)
- Return the angular spread of the detector
delta_width, gamma_width, pixel_width = detector_angle_size(distance, height, widht, pixel)
:param detector_distance_mm: Detector distance from sample in mm
:param height_mm: Detector size in the vertical direction, in mm
:param width_mm: Detector size in the horizontal direction, in mm
:param pixel_size_um: Pixel size in microns
:return x_angle: total angular spread in the diffractometer x-axis, in degrees
:return z_angle: total angular spread in the diffractometer z-axis, in degrees
:return pixel_angle: angular spread per pixel, in degrees
- detector_coverage(wavelength_a=1.5, resolution=0.1, delta=0, gamma=0, detector_distance_mm=565, height_mm=67, width_mm=34)
- Determine volume of reciprocal space covered by the detector based on angular spread
:param wavelength_a: Incicent beam wavelength, in Angstroms
:param resolution: Incident beam resolution, in inverse-Angstroms
:param delta: float or array, detector vertical rotation
:param gamma: float or array, detector horizontal rotation
:param detector_distance_mm: Detector distance from sample in mm
:param height_mm: Detector size in the vertical direction, in mm
:param width_mm: Detector size in the horizontal direction, in mm
:return: volume in inverse-Angstroms
- detector_rotate(detector_position_mm=(0, 1000.0, 0), delta=0.0, gamma=0.0, labmatrix=array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]]))
- Return a position array for a vector rotated by delta and gamma, like a detector along [0,1,0]
:param detector_position_mm: detector position from sample in mm
:param delta: vertical rotation about z-axis in Deg
:param gamma: horizontal rotation about x-axis in Deg
:param labmatrix: [3*3] orientation matrix to convert to alternative basis
:return: array
- detector_volume(wavelength_a=1.5, resolution=0.1, phi=0, chi=0, eta=0, mu=0, delta=0, gamma=0, detector_distance_mm=565, height_mm=67, width_mm=34, lab=array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]]))
- Determine volume of reciprocal space covered by the detector, return list of voxels covered by detector
total_volume, hkl = detector_volume(1.5, 0.1, chi=90, eta=30, delta=60)
The returned list of coordinates (hkl) is defined in the sample frame, where each coordinate specifies a voxel
in reciprocal space with size resolution(inverse-Anstroms) ** 3
As such, the total volume of reciprocal space measured is:
total_volume = len(hkl) * fc.wavevector(energy_kev=energy_range_ev / 1000.) ** 3
:param wavelength_a: Incicent beam wavelength, in Angstroms
:param resolution: Incident beam resolution, in inverse-Angstroms (determines segmentation of calculation)
:param phi: float, phi-axis rotation about sample-z axis
:param chi: float, chi-axis rotation about sample-y' axis
:param eta: float, eta-axis rotation about sample-z'' axis
:param mu: float, mu-axis rotation about sample-x''' axis
:param delta: float, detector rotation vertical rotation
:param gamma: float, detector rotation horizontal rotation
:param detector_distance_mm: Detector distance from sample in mm
:param height_mm: Detector size in the vertical direction, in mm
:param width_mm: Detector size in the horizontal direction, in mm
:param lab: [3x3] Transformation matrix to change the lab coordinate system
:return total_volume: float, total volume of reciprocal space in inverse Angstroms
:return hkl: [nx3] array of voxels covered by detector, integer coordinates in the sample frame
- detector_volume_scan(wavelength_a=1.5, resolution=0.1, phi=0, chi=0, eta=0, mu=0, delta=0, gamma=0, detector_distance_mm=565, height_mm=67, width_mm=34, lab=array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]]))
- Return total reciprocal space volume covered by scanning an axis with a detector
total, hkl, overlaps = detector_volume_scan(1.5, 0.1, phi=np.arange(-180,180))
Rotation axes can be specified as either floats or arrays, where all arrays must have the same length.
:param wavelength_a: Incicent beam wavelength, in Angstroms
:param resolution: Incident beam resolution, in inverse-Angstroms (determines segmentation of calculation)
:param phi: float or array, phi-axis about sample-z axis
:param chi: float or array, chi-axis about sample-y' axis
:param eta: float or array, eta-axis about sample-z'' axis
:param mu: float or array, mu-axis about sample-x''' axis
:param delta: float or array, detector vertical rotation
:param gamma: float or array, detector horizontal rotation
:param detector_distance_mm: Detector distance from sample in mm
:param height_mm: Detector size in the vertical direction, in mm
:param width_mm: Detector size in the horizontal direction, in mm
:param lab: [3x3] Transformation matrix to change the lab coordinate system
:return total: float, total volume covered, in cubic inverse Angstroms
:return hkl: [nx3] array of voxels covered by detector, integer coordinates in the sample frame
:return overlaps: [n] array of the number of times each voxel has been repeatedly measured (0 = only measurred once)
- diff2lab(vec, lab=None)
- Convert between diffractometer frame and lab frame
Lab frame according to Diamond I16 beamline
Diffractometer frame according to Fig. 1, H. You, J. Appl. Cryst 32 (1999), 614-623
z-axis : axis parallel to the phi rotation axis when all angles 0 (towards wall (+x) in lab frame)
x-axis : vector normal to phi axis where phi=0 (toward ceiling (+y) in lab frame)
y-axis : vector normal to x,z axes (parallel to beam (+z) in lab frame)
:param vec: [3*n] array of vectors
:param lab: [3*3] transformation matrix, None=((0,1,0),(0,0,1),(1,0,0))
:return: [3*n] array of vectors
- diff6circle2hkl(ub, phi=0, chi=0, eta=0, mu=0, delta=0, gamma=0, energy_kev=None, wavelength=1.0, lab=None)
- Return [h,k,l] position of diffractometer axes with given UB and energy
:param ub: [3*3] array UB orientation matrix following Busing & Levy
:param phi: float sample angle in degrees
:param chi: float sample angle in degrees
:param eta: float sample angle in degrees
:param mu: float sample angle in degrees
:param delta: float detector angle in degrees
:param gamma: float detector angle in degrees
:param energy_kev: float energy in KeV
:param wavelength: float wavelength in A
:param lab: [3*3] lab transformation matrix
:return: [h,k,l]
- diff6circlek(delta, gamma, energy_kev=None, wavelength=1.0, lab=None)
- Calcualte incident and final wavevectors in diffractometer axis using detector angles
:param delta: float angle in degrees in vertical direction (about diff-z)
:param gamma: float angle in degrees in horizontal direction (about diff-x)
:param energy_kev: float energy in KeV
:param wavelength: float wavelength in A
:param lab: [3*3] lab transformation matrix
:return: [1*3], [1*3] : ki, kf
- diff6circleq(delta, gamma, energy_kev=None, wavelength=1.0, lab=None)
- Calcualte wavevector in diffractometer axis using detector angles
:param delta: float angle in degrees in vertical direction (about diff-z)
:param gamma: float angle in degrees in horizontal direction (about diff-x)
:param energy_kev: float energy in KeV
:param wavelength: float wavelength in A
:param lab: [3*3] lab transformation matrix
:return: [1*3]
- diffractometer_Q(eta, delta, energy_kev=8.0)
- Calculate wavevector transfer, Q for diffractometer within the scattering plane.
Qx,Qy = diffractometer_Q(eta,delta,energy_kev)
eta = angle (deg) of sample
delta = angle (deg) of detector
energy_kev = energy in keV
Coordinate system (right handed):
x - direction along beam, +ve is from source to sample
y - direction verticle
z - direction horizontal
Note: Currently only in the verticle geometry!
- diffractometer_rotation(phi=0, chi=0, eta=0, mu=0)
- Generate the 6-axis diffracometer rotation matrix
R = M * E * X * P
Also called Z in H. You, J. Appl. Cryst 32 (1999), 614-623
The diffractometer coordinate system has the convention (all angles zero):
x-axis points vertically, perpendicular to beam (mu is about x)
y-axis points along the direction of the beam
z-axis points along the phi axis, perpendicular to x and y
The vertical scattering plane is in the y-x axis
The horizontal scattering plane is in the y-z axis
vec' = np.dot(diffractometer_rotation(phi, chi, eta, mu), vec)
vec must be 1D or column vector (3*n)
:param phi: float angle in degrees, left handed roation about z'''
:param chi: float angle in degrees, right handed rotation about y''
:param eta: float angle in degrees, left handed rotation about z'
:param mu: float angle in degrees, right handed rotation about x
:return: [3*3] array
- diffractometer_step(wavelength_a=1.5, resolution=0.1, phi=0, chi=0, eta=0, mu=0, delta=0, gamma=0, lab=array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]]))
- Determine the euler angle steps required to scan through reciprocal space at the required resolutuion
phi_step, chi_step, eta_step, mu_step = diffractometer_step(1.5, 0.1, chi=90, eta=20, delta=40)
The returned step size will provide a rotation that moves the wavevector transfer by approximately the resolutuion.
Any steps returning 0 are unsensitive to the rotation in this position
:param wavelength_a: Incicent beam wavelength, in Angstroms
:param resolution: float, combined resolution required, in inverse Angstroms
:param phi: float, phi-axis about sample-z axis
:param chi: float, chi-axis about sample-y' axis
:param eta: float, eta-axis about sample-z'' axis
:param mu: float, mu-axis about sample-x''' axis
:param delta: float, detector vertical rotation
:param gamma: float, detector horizontal rotation
:param lab: [3x3] Transformation matrix to change the lab coordinate system
:returns: phi_step, chi_step, eta_step, mu_step
- dspace2q(dspace)
- Calculate d-spacing from |Q|
Qmag = q2dspace(dspace)
- electron_energy(wavelength_a)
- Calcualte the electron energy in electronvolts using DeBroglie's formula
E [eV] ~ 1.5 / lambda^2 [nm]
:param wavelength_a: electron wavelength in Angstroms
:return: energy in eV
- electron_scattering_factor(element, Qmag=0)
- Read X-ray scattering factor table, calculate f(|Q|)
Uses the coefficients for analytical approximation to the scattering factors
Peng, L. M.; Acta Crystallogr A 1996, 52 (2), 257–276.
Peng, L.-M. Acta Cryst A 1998, 54 (4), 481–485.
Qff = xray_scattering_factor(element, Qmag=[0])
:param element: [n*str] list or array of elements
:param Qmag: [m] array of wavevector distance, in A^-1
:return: [m*n] array of scattering factors
- electron_wavelength(energy_ev)
- Calcualte the electron wavelength in Angstroms using DeBroglie's formula
lambda [nm] ~ sqrt( 1.5 / E [eV] )
:param energy_ev: electron energy in eV
:return: wavelength in Anstroms
- element_charge_string(symbol, occupancy=1.0, charge=0.0, latex=False)
- Return formatted string of element with occupancy and charge
:param symbol: str - element string
:param occupancy: float - element occupancy or number of elements
:param charge: float - element charge
:param latex: if True, returns string formatted with latex tags
:return: str
- element_name(element=None)
- Returns the element name
:param element: str
:return: int
- element_symbol(element_Z=None)
- Returns the element sympol for element_Z
:param element_z: int or array or None for all elements
:return: str
- element_z(element)
- Returns the element number Z
:param element: str
:return: int
- energy2wave(energy_kev)
- Converts energy in keV to wavelength in A
wavelength_a = energy2wave(energy_kev)
lambda [A] = h*c/E = 12.3984 / E [keV]
- euler_moment(mxmymz, uv)
- Convert moment mxmymz coordinates from cif into eulerian basis
:param mxmymz: [nx3] array, units of Bohr magneton, directed along a,b,c
:param uv: [3x3] array, basis vectors [a,b,c]
:return: moments [nx3] array, units of Bohr magneton, directed along x,y,z
- euler_unit_vector(uvw, uv)
- Convert vector in a specific basis to a cartesian basis and normalise to a unit vector
:param uvw: [nx3] array as [[u,v,w]]
:param uv: [3x3], basis vectors [a,b,c]
:return: [nx3] array xyz/|xyz|, where x,y,z = u*a+v*b+w*c
- filter_transmission(chemical_formula, energy_kev, density, thickness_um=100)
- Calculate transmission of x-ray through a slab of material
Equivalent to https://henke.lbl.gov/optical_constants/filter2.html
Based on formulas from: Henke, Gullikson, and Davis, Atomic Data and Nuclear Data Tables 54 no.2, 181-342 (July 1993)
:param chemical_formula: str molecular formula
:param energy_kev: float or array, x-ray energy in keV
:param density: float density in g/cm^3
:param thickness_um: slab thickness in microns
:return: float or array
- find_spacegroup(sg_symbol)
- Find a spacegroup based on the identifying symbol
:param sg_symbol: str, e.g. 'Fd-3m'
:return: spacegroup dict or None if not found
- fitincell(uvw)
- Set all fractional coodinates between 0 and 1
Usage:
uvw = fitincell(uvw)
uvw = [[nx3]] array of fractional vectors [u,v,w]
- genHKL(H, K=None, L=None)
- Generate HKL array with all combinations within range specified
Usage:
HKL = genHKL(max)
int max = generates each h,k,l from -max to max
HKL = genHKL([min,max])
int min, int max = generates h,l,l from min to max
HKL = genHKL([hmin,hmax],[kmin,kmax],[lmin,lmax])
hmin,hmax = min and max values for h, k and l respectivley
array HKL = [[nx3]] array of [h,k,l] vectors
E.G.
HKL = genHKL(-3)
E.G.
HKL = genHKL([-1,1])
E.G.
HKL = genHKL([-2,2],[0,3],[1,1])
- gen_sym_axial_vector(sym_ops, x, y, z)
- Transform axial vector by symmetry operations
Usage:
uvw = gen_symcen_pos(sym_ops,cen_ops,x,y,z)
sym_ops = [n*'x,y,z'] array of string symmetry operations
cen_ops = [m*'x,y,z'] array of string centring operations
x,y,z = fractional coordinates of atomic posiiton to be modified by symmetry
uvw = [[nx3]] array of symmetry defined factional coordinates [u,v,w]
E.G.
uvw = gen_symcen_pos(['x,y,z','y,-x,z+1/2'],['x,y,z','x+1/3,y+1/3,z'],0.1,0.2,0.3)
uvw >> [[0.1,0.2,0.3] , [0.433,0.533,0.3] , [0.2,-0.1,0.8] , [0.533,-0.233,0.8]]
:param sym_ops:
:param x:
:param y:
:param z:
:return:
- gen_sym_mat(sym_ops)
- Generate transformation matrix from symmetry operation
Currently very ugly but it seems to work
Tested in Test/test_gen_sym_mat - found to be fast and reliable.
sym_mat = gen_sym_mat(['x,y,z','y,-x,z+1/2'])
sym_mat[0] = [[ 1., 0., 0., 0.],
[ 0., 1., 0., 0.],
[ 0., 0., 1., 0.],
[ 0., 0., 0., 1.]])
sym_mat[1] = [[ 0. , 1. , 0. , 0. ],
[-1. , 0. , 0. , 0. ],
[ 0. , 0. , 1. , 0.5],
[ 0., 0., 0., 1.]]
- gen_sym_pos(sym_ops, x, y, z)
- Generate positions from symmetry operations
Usage:
uvw = gen_sym_pos(sym_ops,x,y,z)
sym_ops = [n*'x,y,z'] array of string symmetry operations
x,y,z = fractional coordinates of atomic posiiton to be modified by symmetry
uvw = [[nx3]] array of symmetry defined factional coordinates [u,v,w]
E.G.
uvw = gen_sym_pos(['x,y,z','y,-x,z+1/2'],0.1,0.2,0.3)
uvw >> [[0.1,0.2,0.3] , [0.2,-0.1,0.8]]
- gen_sym_ref(sym_ops, hkl)
- Generate symmetric reflections given symmetry operations
symhkl = gen_sym_ref(sym_ops,h,k,l)
- gen_sym_unique(sym_ops, x, y, z, cen_ops=None)
- Generate positions from symmetry operations with idential positions removed
Usage:
uvw = gen_sym_unique(sym_ops,x,y,z)
E.G.
uvw = gen_sym_unique(['x,y,z','y,-x,z+1/2','x,y,z'],0.1,0.2,0.3)
uvw >> [[0.1,0.2,0.3] , [0.2,-0.1,0.8]]
:param sym_ops: list of str - symmetry operations
:param x: float
:param y: float
:param z: float
:param cen_ops: Optional - list of str for centring operations
:return: array of positions
- gen_symcen_ops(sym_ops, cen_ops)
- Build complete list of symmetry operations from symmetry and centring vectors
Usage:
ops = gen_symcen_ops(sym_ops,cen_ops)
sym_ops = [n*'x,y,z'] array of string symmetry operations
cen_ops = [m*'x,y,z'] array of string centring operations
ops = [n*m*'x,y,z'] array of string symmetry operations
E.G.
ops = gen_symcen_pos(['x,y,z','y,-x,z+1/2'],['x,y,z','x+1/3,y+1/3,z'])
>> ops = ['x,y,z','x+1/3,y+1/3,z','y,-x,z+1/2','y+1/3,-x+1/3,z+1/2']
- gen_symcen_pos(sym_ops, cen_ops, x, y, z)
- Generate positions from symmetry and centring operations
Usage:
uvw = gen_symcen_pos(sym_ops,cen_ops,x,y,z)
sym_ops = [n*'x,y,z'] array of string symmetry operations
cen_ops = [m*'x,y,z'] array of string centring operations
x,y,z = fractional coordinates of atomic posiiton to be modified by symmetry
uvw = [[nx3]] array of symmetry defined factional coordinates [u,v,w]
E.G.
uvw = gen_symcen_pos(['x,y,z','y,-x,z+1/2'],['x,y,z','x+1/3,y+1/3,z'],0.1,0.2,0.3)
uvw >> [[0.1,0.2,0.3] , [0.433,0.533,0.3] , [0.2,-0.1,0.8] , [0.533,-0.233,0.8]]
- getenergy()
- group_intensities(q_values, intensity, min_overlap=0.01)
- Group reflections within the overlap, returning the index max intensity of each group
:param q_values: [1*n] array of floats, position parameter of each reflection
:param intensity: [1*n] array of floats, intensity parameter of each reflection
:param min_overlap: float, how close the reflections are to be grouped
:return: group_idx: [1*m] array of int index
- hkl2Q(hkl, UVstar)
- Convert reflection indices (hkl) to orthogonal basis in A-1
:param hkl: [nx3] array of reflections
:param UV: [3x3] array of unit cell vectors [[a1,a2,a3],[b1,b2,b3],[c1,c2,c3]]
:return: [nx3] array of wavevectors in an orthogonal basis, in A-1
- hkl2Qmag(hkl, UVstar)
- Calcualte magnitude of Q from hkl reflection
:param hkl: [nx3] array of reflections
:param UV: [3x3] array of unit cell vectors
:return: [nx1] array of wavevector magnitudes, in A-1
- hkl2dspace(hkl, UVstar)
- Calcualte d-spacing from hkl reflection
:param hkl: [nx3] array of reflections
:param UV: [3x3] array of reciprocal unit cell vectors
:return: [nx1] array of d-spacing in A
- hkl2str(hkl)
- Convert hkl to string (h,k,l)
:param hkl:
:return: str '(h,k,l)'
- hkl2twotheta(hkl, UVstar, energy_kev=17.794, wavelength_a=None)
- Calcualte d-spacing from hkl reflection
:param hkl: [nx3] array of reflections
:param UV: [3x3] array of unit cell vectors
:param energy_kev: float energy in keV
:param wavelength_a: float wavelength in Angstroms
:return: [nx1] array of d-spacing in A
- indx(coords, basis_vectors)
- Index cartesian coordinates on a lattice defined by basis vectors
Usage (reciprocal space):
[[h, k, l], ...] = index_lattice([[qx, qy, qz], ...], [a*, b*, c*])
Usage (direct space):
[u, v, w] = index_lattice([x, y, z], [a, b, c])
:param coords: [nx3] array of coordinates
:param basis_vectors: [3*3] array of basis vectors [a[3], b[3], c[3]]
:return: [nx3] array of vectors in units of reciprocal lattice vectors
- invert_sym(sym_op)
- Invert the sign of the given symmetry operation
Usage:
new_op = invert_sym(sym_op)
sym_op = str symmetry operation e.g. 'x,y,z'
new_op = inverted symmetry
E.G.
new_op = invert_sym('x,y,z')
>> new_op = '-x,-y,-z'
- labvector(vec, U=None, R=None, LAB=None)
- Transform any vector through the orientation, rotation and lab transformations
:param vec: [n*3] array of vectors in the diffractometer frame
:param U: [3*3] oritenation matrix (see umatrix)
:param R: [3x3] rotation matrix (see diffractometer_rotation)
:param LAB: [3x3] transformation matrix between diffractometer frame and lab frame
:return: [n*3] array of Q vectors in the lab coordinate system
- labwavevector(hkl, UV, U=None, R=None, LAB=None)
- Calculate the lab wavevector using the unit-vector, oritenation matrix and rotation matrix
Returns vectors in the lab coordinate system, by default defined like Diamond Light Source:
x-axis : away from synchrotron ring, towards wall
y-axis : towards ceiling
z-axis : along beam direction
:param hkl: [3xn] array of (h, k, l) reciprocal lattice vectors
:param UV: [3*3] Unit-vector matrix (see latpar2ub_rot)
:param U: [3*3] oritenation matrix (see umatrix)
:param R: [3x3] rotation matrix (see diffractometer_rotation)
:param LAB: [3x3] transformation matrix between diffractometer frame and lab frame
:return: [3xn] array of Q vectors in the lab coordinate system
- latpar2uv(*lattice_parameters, **kwargs)
- Convert a,b,c,alpha,beta,gamma to UV=[A,B,C]
UV = latpar2uv(a,b,c,alpha=90.,beta=90.,gamma=120.)
Vector c is defined along [0,0,1]
Vector a and b are defined by the angles
- latpar2uv_rot(*lattice_parameters, **kwargs)
- Convert a,b,c,alpha,beta,gamma to UV=[A,B,C]
UV = latpar2uv_rot(a,b,c,alpha=90.,beta=90.,gamma=120.)
Vector b is defined along [0,1,0]
Vector a and c are defined by the angles
- lattice_hkl2dspace(hkl, *lattice_parameters, **kwargs)
- Calcualte dspace from lattice parameters
:param hkl: [nx3] array of reflections
:param lattice_parameters: a,b,c,alpha,beta,gamma
:return: float, d-spacing in A
- lattice_hkl2twotheta(hkl, *lattice_parameters, energy_kev=17.794, wavelength_a=None, **kwargs)
- Calcualte dspace from lattice parameters
:param hkl: [nx3] array of reflections
:param energy_kev: float, radiation energy in keV
:param lattice_parameters: a,b,c,alpha,beta,gamma
:return: float, d-spacing in A
- load_pointgroup(pg_number)
- Load point group using number
Point Groups:
Triclinic
1 C1 ( 1) GenPos: 1
2 Ci ( -1) GenPos: 2
Monoclinic
3 C2 ( 2) GenPos: 2
4 Cs ( m) GenPos: 2
5 C2h ( 2/m) GenPos: 4
Orthorhombic
6 D2 ( 222) GenPos: 4
7 C2v ( mm2) GenPos: 4
8 D2h ( mmm) GenPos: 8
Tetragonal
9 C4 ( 4) GenPos: 4
10 S4 ( -4) GenPos: 4
11 C4h ( 4/m) GenPos: 8
12 D4 ( 422) GenPos: 8
13 C4v ( 4mm) GenPos: 8
14 D2d ( -42m) GenPos: 8
15 D4h (4/mmm) GenPos: 16
Trigonal
16 C3 ( 3) GenPos: 3
17 C3i ( -3) GenPos: 6
18 D3 ( 312) GenPos: 6
19 C3v ( 3m1) GenPos: 6
20 D3d ( -31m) GenPos: 12
Hexagonal
21 C6 ( 6) GenPos: 6
22 C3h ( -6) GenPos: 6
23 C6h ( 6/m) GenPos: 12
24 D6 ( 622) GenPos: 12
25 C6v ( 6mm) GenPos: 12
26 D3h ( -6m2) GenPos: 12
27 D6h (6/mmm) GenPos: 24
Cubic
28 T ( 23) GenPos: 12
29 Th ( m-3) GenPos: 24
30 O ( 432) GenPos: 24
31 Td ( -43m) GenPos: 24
32 Oh ( m-3m) GenPos: 48
:param pg_number: int or str, e.g. 'cubic'
:return: dict
- magnetic_form_factor(element, Qmag=0.0)
- Read Magnetic form factor table, calculate <j0(|Q|)>
Analytical approximation of the magnetic form factor:
<j0(|Q|)> = A*exp(-a*s^2) + B*exp(-b*s^2) + C*exp(-c*s^2) + D, where s = sin(theta)/lambda in A-1
See more about the approximatio here: https://www.ill.eu/sites/ccsl/ffacts/ffactnode3.html
Note: Currently only J0 terms are used and 5d atoms are not currently included
Usage:
Qff = read_mff(element,Qmag)
element = str element name, e.g. 'Co'
Qmag = magnitude of Q=sin(theta)/lambda in A-1 at which to calcualte, can be a list or array to return multiple values
Qff = Magnetic form factor for element at Qmag
E.G.
Qff = read_mff('Co',np.arange(0,4,0.1))
- maxHKL(Qmax, UV)
- Returns the maximum indexes for given max radius
e.g.
UVstar = RcSp([[3,0,0],[0,3,0],[0,0,10]]) # A^-1
Qmax = 4.5 # A^-1
max_hkl = maxHKL(Qmax,UVstar)
max_hkl =
>>> [3,3,8]
- molecular_attenuation_length(chemical_formula, energy_kev, density, grazing_angle=90)
- Calcualte X-Ray Attenuation Length
Equivalent to: https://henke.lbl.gov/optical_constants/atten2.html
Based on formulas from: Henke, Gullikson, and Davis, Atomic Data and Nuclear Data Tables 54 no.2, 181-342 (July 1993)
:param chemical_formula: str molecular formula
:param energy_kev: float or array, x-ray energy in keV
:param density: float density in g/cm^3
:param grazing_angle: incidence angle relative to the surface, in degrees
:return: float or array, in microns
- molecular_reflectivity(chemical_formula, energy_kev, density, grazing_angle)
- Calculate the specular reflectivity of a material
From: https://xdb.lbl.gov/Section4/Sec_4-2.html
:param chemical_formula: str molecular formula
:param energy_kev: float or array, x-ray energy in keV
:param density: float, density in g/cm^3
:param grazing_angle: float, incidence angle relative to the surface, in degrees
:return: float or array
- molecular_refractive_index(chemical_formula, energy_kev, density)
- Calculate Complex Index of Refraction
n = 1 - (1/2pi)N*r0*lambda^2*(f1+if2) = 1 - Delta - iBeta
Equivalent to: https://henke.lbl.gov/optical_constants/getdb2.html
Based on formulas from: Henke, Gullikson, and Davis, Atomic Data and Nuclear Data Tables 54 no.2, 181-342 (July 1993)
:param chemical_formula: str molecular formula
:param energy_kev: float or array, x-ray energy in keV
:param density: float density in g/cm^3
:return: n(complex), Delta, Beta
- molecular_weight(compound_name)
- Calculate the molecular weight of given compound
:param compound_name: str elements
:return: float weight in g
- neutron_energy(wavelength_a)
- Calcualte the neutron energy in milli-electronvolts using DeBroglie's formula
E [meV] ~ 81.82 / lambda^2 [A]
:param wavelength_a: neutron wavelength in Angstroms
:return: energy in meV
- neutron_scattering_length(elements, table='neutron data booklet')
- Return neutron scattering length, b, in fm
b = neutron_scattering_length('Co')
Now includes complex neutron scattering lengths for isotopes from package periodictable
b = neutron_scattering_length('7-Li')
Lists of elements also allowed
[bLi, bCo, bO] = neutron_scattering_length(['7-Li', 'Co', 'O'])
Default values are extracted from Periodic Table https://github.com/pkienzle/periodictable
- Values originally from Neutron Data Booklet, by A-J Dianoux, G. Lander (2003), with additions and corrections upto v1.7.0 (2023)
Alternative values are also available:
- ITC Vol. C, Section 4.4.4., By V. F. Sears Table 4.4.4.1 (Jan 1995)
:param elements: [n*str] list or array of elements
:param table: name of data table to use, options are 'neutron data booklet' or 'sears'
:return: [n] array of scattering lengths
- neutron_wavelength(energy_mev)
- Calcualte the neutron wavelength in Angstroms using DeBroglie's formula
lambda [A] ~ sqrt( 81.82 / E [meV] )
:param energy_mev: neutron energy in meV
:return: wavelength in Anstroms
- orbital_configuration(element, charge=None)
- Returns the orbital configuration of an element as a list of strings
:param element: str, element name, e.g. 'Fe' or 'Fe3+' or '0.8Fe2+'
:param charge: int, element charge (overwrites charge given in element)
:return: ['1s2', '2s2', '2p6', ...]
- orthogonal_axes(x_axis=(1, 0, 0), y_axis=(0, 1, 0))
- Returns orthogonal right-handed cartesian axes based on the plane of two non-perpendicular vectors
E.G.
x,y,z = orthogonal_axes([1,0,0],[0.5,0.5,0])
>> x = array([1,0,0])
>> y = array([0,1,0])
>> z = array([0,0,1])
E.G.
x,y,z = orthogonal_axes([0,1,0],[0,0,1])
>> x = array([0,1,0])
>> y = array([0,0,1])
>> z = array([1,0,0])
- peaks_on_plane(peak_x, peak_y, peak_height, peak_width, max_x, max_y, pixels_width=1001, background=0)
- Creates a rectangular grid and adds Gaussian peaks with height "intensity"
:param peak_x: [nx1] array of x coordinates
:param peak_y: [nx1] array of y coordinates
:param peak_height: [nx1] array of peak heights
:param peak_width: [nx1] or float, gaussian width
:param max_x: grid will be created from -max_x : +max_x horizontally
:param max_y: grid will be created from -max_y : +max_y vertically
:param pixels_width: grid will contain pixels horizontally and the number vertically will be scaled
:param background: if >0, add a normaly distributed background with average level = background
:return: x, y, plane
- peakwidth_deg(domain_size_a, twotheta, wavelength_a=None, energy_kev=None, instrument_resolution=0)
- Return the peak width in degrees for a given two-theta based on the
crystallite domain size and instrument resolution.
Equivalent to the Scherrer equation with shape factor 1.0
:param domain_size_a: crystallite domain size in Anstroms
:param twotheta: scattering angle in degrees
:param wavelength_a: incident beam wavelength, in Angstroms
:param energy_kev: or, incident beam energy, in keV
:param instrument_resolution: instrument resolution in inverse Anstroms
:return:
- photoabsorption_crosssection(elements, energy_kev)
- Calculate the photoabsorption cross section from the atomic scattering factors
u = 2*r0*lambda*f2
See: https://henke.lbl.gov/optical_constants/intro.html
:param elements: str or list of string element symbol, if list, absorption will be summed over elements
:param energy_kev: float or array x-ray energy
:return: float or array [len(energy)] m^2
- pointgroups()
- Read pointgroup file, return dict
- powder_average(tth, energy_kev)
- Return the powder average correction for intensities at a given two-theta
Ip = I0*PA, PA = 1/|Q|^2
:param tth: two-theta in deg
:param energy_kev: energy in keV
:return: PA
- print_atom_properties(elements=None)
- Outputs string of stored atomic properties
:param elements: str or list or None
str: 'Co'
list: ['Co', 'O']
:return: str
- q2dspace(qmag)
- Calculate d-spacing from |Q|
dspace = q2dspace(Qmag)
- q2units(qmag, units='tth', energy_kev=None)
- Convert |Q| in A^-1 to choice of units
:param qmag: float or array in inverse-Angstrom
:param units: str: 'tth', 'dspace', 'q' (raises ValueError if wrong)
:param energy_kev: float or None
:return: float or array
- read_atom_properties_file(filedir)
- Reads the text file "Dans Element Properties.txt"
Returns a list of dicts containing atomic properites from multiple sources
data = read_atom_properties_file(filedir)
data[22]['Element']
:param filedir: location of "Dans Element Properties.txt"
:return: [dict, ...]
- read_neutron_scattering_lengths(table='neutron data booklet')
- Read neutron scattering length of element or isotope
Returns table of complex bound coherent neutron scattering length, in fm for elements and isotopes
Natural average for each element given by 'element', e.g. 'Ti'
Isotope value given by 'weight-element', e.g. '46-Ti'
Default values are extracted from Periodic Table https://github.com/pkienzle/periodictable
- Values originally from Neutron Data Booklet, by A-J Dianoux, G. Lander (2003), with additions and corrections upto v1.7.0 (2023)
Alternative values are also available:
- ITC Vol. C, Section 4.4.4., By V. F. Sears Table 4.4.4.1 (Jan 1995)
:param table: name of data table to use, options are 'neutron data booklet' or 'sears'
:return: {'isotope': complex, ...}
- readcif(filename=None, debug=False)
- Open a Crystallographic Information File (*.cif) file and store all entries in a key:value dictionary
Looped values are stored as lists under a single key entry
All values are stored as strings
E.G.
crys=readcif('somefile.cif')
crys['_cell_length_a'] = '2.835(2)'
crys[key] = value
available keys are give by crys.keys()
To debug the file with outputted messages, use:
cif = readcif(file, debug=True)
Some useful standard CIF keywords:
_cell_length_a
_cell_length_b
_cell_length_c
_cell_angle_alpha
_cell_angle_beta
_cell_angle_gamma
_space_group_symop_operation_xyz
_atom_site_label
_atom_site_type_symbol
_atom_site_occupancy
_atom_site_U_iso_or_equiv
_atom_site_fract_x
_atom_site_fract_y
_atom_site_fract_z
- reciprocal_volume(twotheta, twotheta_min=0, energy_kev=None, wavelength_a=1.5)
- Calculate the volume of reciprocal space covered between two scattering angles
:param twotheta: larger scattering angle (Bragg angle, 2theta)
:param twotheta_min: smaller scattering angle
:param energy_kev: photon energy, in keV
:param wavelength_a: wavelength in Angstroms
:return: float, volume, in Angstroms^-3
- reflections_on_detector(qxqyqz, energy_kev, det_distance=1.0, det_normal=(0, -1.0, 0), delta=0.0, gamma=0.0, det_width=1.0, det_height=1.0, labmatrix=array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]]))
- Return relative position of reflection on detector
:param qxqyqz: [nx3] array of reflection coordinates in Q-space [qx, qy, qz]
:param energy_kev: float, Incident beam energy in keV
:param det_distance: float, Detector distance in meters
:param det_normal: (dx,dy,dz) direction of detector normal
:param delta: float, angle in degrees in vertical direction (about diff-z)
:param gamma: float angle in degrees in horizontal direction (about diff-x)
:param det_width: float, detector width along x-axis in meters
:param det_height: float, detector height along z-axis in meters
:param labmatrix: [3x3] orientation array to convert to difference basis
:return uvw: [nx3] array of positions relative to the centre of the detector, or NaN if not incident
:return wavevector_difference: [n] array of wavevector difference in A-1
- resolution2energy(res, twotheta=180.0)
- Calcualte the energy required to achieve a specific resolution at a given two-theta
:param res: measurement resolution in A (==d-spacing)
:param twotheta: Bragg angle in Degrees
:return: float
- rotmatrixx(mu)
- Generate diffractometer rotation matrix mu about x-axis (right handed)
Equivalent to ROLL in the Tait–Bryan convention
Equivalent to mu in You et al. diffractometer convention (right handed)
r = rotmatrix_x(mu)
vec' = np.dot(r, vec)
vec must be 1D or column vector (3*n)
:param mu: float angle in degrees
:return: [3*3] array
- rotmatrixy(chi)
- Generate diffractometer rotation matrix chi about y-axis (right handed)
Equivalent to PITCH in the Tait–Bryan convention
Equivalent to -chi in You et al. diffractometer convention (left handed)
r = rotmatrix_y(chi)
vec' = np.dot(r, vec)
vec must be 1D or column vector (3*n)
:param chi: float angle in degrees
:return: [3*3] array
- rotmatrixz(phi)
- Generate diffractometer rotation matrix about z-axis (right handed)
Equivalent to YAW in the Tait-Bryan convention
Equivalent to -phi, -eta, -delta in You et al. diffractometer convention (left handed)
r = rotmatrix_z(phi)
vec' = np.dot(r, vec)
vec must be 1D or column vector (3*n)
:param phi: float angle in degrees
:return: [3*3] array
- scale_intensity(intensity, wavevector_diff, resolution=0.5)
- Scale intensity depending on wavevector difference and resolution
:param intensity: intensity value
:param wavevector_diff: distance from centre in inverse angstroms
:param resolution: resolution in inverse angstroms
:return:
- scherrer_fwhm(size, twotheta, wavelength_a=None, energy_kev=None, shape_factor=0.9)
- Use the Scherrer equation to calculate the size of a crystallite from a peak width
L = K * lambda / fwhm * cos(theta)
See: https://en.wikipedia.org/wiki/Scherrer_equation
:param size: crystallite domain size in Angstroms
:param twotheta: 2*Bragg angle, in degrees
:param wavelength_a: incident beam wavelength, in Angstroms
:param energy_kev: or, incident beam energy, in keV
:param shape_factor: dimensionless shape factor, dependent on shape of crystallite
:return: float, peak full-width-at-half-max in degrees
- scherrer_size(fwhm, twotheta, wavelength_a=None, energy_kev=None, shape_factor=0.9)
- Use the Scherrer equation to calculate the size of a crystallite from a peak width
L = K * lambda / fwhm * cos(theta)
See: https://en.wikipedia.org/wiki/Scherrer_equation
:param fwhm: full-width-half-maximum of a peak, in degrees
:param twotheta: 2*Bragg angle, in degrees
:param wavelength_a: incident beam wavelength, in Angstroms
:param energy_kev: or, incident beam energy, in keV
:param shape_factor: dimensionless shape factor, dependent on shape of crystallite
:return: float, crystallite domain size in Angstroms
- spacegroup(sg_number)
- Return a dict of information for a space group
:param sg_number: int space group number, as in the international tables of Crystallography
:return: dict
- spacegroup_list(sg_numbers=None)
- Return a structured list of space groups with general operations
:param sg_numbers: list of space group numbers (None for whole list)
:return: str
- spacegroup_magnetic(msg_number)
- Return dict of magnetic spacegroup, given magnetic spacegroup number
:param msg_number: magnetic space group number e.g. 61.433
:return: dict with keys:
'parent number': sg,
'space group number': number,
'space group name': label,
'setting': setting,
'type name': type_name,
'related group': rel_number,
'related name': rel_name,
'related setting': rel_setting,
'operators general': xyz_op,
'operators magnetic': mxmymz_op,
'operators time': time,
- spacegroup_magnetic_list(sg_number=None, sg_dict=None)
- Return str list of magnetic space groups
:param sg_number: space group number (1-230)
:param sg_dict: alternate input, spacegroup dict from spacegroup function
:return: str
- spacegroup_subgroups(sg_number)
- Return dict of maximal subgroups for spacegroup
:param sg_number: space group number (1-230)
:return: dict
- spacegroup_subgroups_list(sg_number=None, sg_dict=None)
- Return str of maximal subgroups for spacegroup
:param sg_number: space group number (1-230)
:param sg_dict: alternate input, spacegroup dict from spacegroup function
:return: str
- spacegroups()
- Return a dict of all space groups
Loaded from json file created from the Bilbao crystallographic server: https://www.cryst.ehu.es/
:return: dict with keys:
'space group number'
'space group name html'
'space group name'
'web address generator'
'web address wyckoff'
'web address site check' # address % (u, v, w),
'general positions'
'magnetic space groups',
'positions centring'
'positions multiplicity'
'positions wyckoff letter'
'positions symmetry'
'positions coordinates'
'subgroup number',
'subgroup name',
'subgroup index',
'subgroup type'
- spacegroups_magnetic(sg_number=None, sg_dict=None)
- Returns dict of magnetic space groups for required space group
:param sg_number: space group number (1-230) or None to return all magnetic spacegroups
:param sg_dict: alternate input, spacegroup dict from spacegroup function
:return: dict
- split_compound(compound_name)
- Convert a molecular or compound name into a list of elements and numbers.
Assumes all element multiplications are to the LEFT of the element name.
Values in brackets are multiplied out.
E.g.
split_compound('Mn0.3(Fe3.6(Co1.2)2)4(Mo0.7Pr44)3')
>> ['Mn0.3', 'Fe14.4', 'Co9.6', 'Mo2.1', 'Pr132']
:param compound_name: str
:return: list of str
- split_element_symbol(element)
- From element symbol, split charge and occupancy
symbol, occupancy, charge = split_element_symbol('Co3+')
Any numbers appended by +/- are taken as charge, otherwise they are counted as occupancy.
e.g. element > symbol | occupancy | charge
Co3+ Co 1. 3
3.2O2- O 3.2 -2
fe3 Fe 3 0
:param element: str
:return: symbol: str
:return: occupancy: float
:return: charge: float
- str2element(string)
- Finds element name in string
- sum_sym_ref(symhkl)
- Remove equivalent hkl positions and return the number of times each is generated.
- sym_mat2str(sym_mat, time=None)
- Generate symmetry operation string from matrix
:param sym_mat: array [3x3] or [4x4]
:param time: +/-1 or None
:return: str 'x,y,z(,1)'
- sym_op_det(sym_ops)
- Return the determinant of a symmetry operation
:param sym_ops: str e.g. 'x,-y,z+1/2' or 'y, x+y, -z, -1' or list of str ['x,y,z',...]
:return: float |det| or list of floats
- sym_op_mx(operations)
- Convert each operation from x,y,z to mx,my,mz
:param operations: ['x,y,z',]
:return: ['mx,my,mz',]
- sym_op_recogniser(sym_ops)
- Evaluates symmetry operations and returns str name of operation
Doesn't work yet - works on simple systems but not trigonal or hexagonal operations - for example sg167
- sym_op_time(operations)
- Return the time symmetry of a symmetry operation
:param operations: list(str) e.g. ['x,-y,z+1/2', 'y, x+y, -z, -1']
:return: list, +/-1
- symmetry_ops2magnetic(operations)
- Convert list of string symmetry operations to magnetic symmetry operations
See Vesta_Manual.pdf Section 9.1.1 "Creation and editing of a vector"
Magnetic symmetry
µ' = TPMµ
T = Time operators x,y,z,(+1)
P = Parity operator (determinant of M)
M = Symmetry operator without translations
:param operations: list of str ['x,y,z',]
:return: list of str ['x,y,z']
- ubmatrix(uv, u)
- Return UB matrix (units of 2pi)
:param uv: [3*3] unit vector [a,b,c]
:param u: [3*3] orientation matrix in the diffractometer frame
:return: [3*3] array
- uiso2biso(uiso)
- Convert U isotropic thermal parameters to B isotropic thermal parameters
:param uiso: Uiso value or array
:return: Biso value or array
- umatrix(a_axis=None, b_axis=None, c_axis=None)
- Define an orientation matrix in the diffractometer frame
Diffractometer frame according to Fig. 1, H. You, J. Appl. Cryst 32 (1999), 614-623
z-axis : axis parallel to the phi rotation axis when all angles 0 (towards wall (+x) in lab frame)
x-axis : vector normal to phi axis where phi=0 (toward ceiling (+y) in lab frame)
y-axis : vector normal to x,z axes (parallel to beam (+z) in lab frame)
:param a_axis: direction of a in the diffractometer frame
:param b_axis: direction of b in the diffractometer frame
:param c_axis: direction of c in the diffractometer frame
:return: [3*3] array
- warn(message, category=None, stacklevel=1, source=None)
- Issue a warning, or maybe ignore it or raise an exception.
- wave2energy(wavelength)
- Converts wavelength in A to energy in keV
energy_kev = wave2energy(wavelength_a)
Energy [keV] = h*c/L = 12.3984 / lambda [A]
- wavevector(energy_kev=None, wavelength=None)
- Return wavevector = 2pi/lambda
- wavevector_difference(Q, ki)
- Returns the difference between reciprocal lattice coordinates and incident wavevector, in A-1
When the difference is zero, the condition for diffraction is met.
Laue condition: Q = ha* + kb* + lc* == kf - ki
Elastic scattering: |kf| = |ki|
Therefore: |Q + ki| - |ki| = 0
Expanding & simplifing: Q.Q + 2Q.ki = 0
:param Q: [[nx3]] array of reciprocal lattice coordinates, in A-1
:param ki: [x,y,z] incident wavevector, in A-1
:return: [nx1] array of difference, in A-1
- wavevector_resolution(energy_range_ev=200, wavelength_range_a=None, domain_size_a=1000)
- Calculate the combined wavevector resolutuion in inverse Angstroms
Combines instrument incident beam resolution and the mosaic of the crystal
:param energy_range_ev: Incident x-ray beam resolution in eV
:param wavelength_range_a: Incident beam resolution in Angstroms
:param domain_size_a: crysallite size in Angstroms (provides mosic using Scherrer equation)
:return: float, resolutuion in inverse Angstroms
- write_cif(cifvals, filename=None, comments=None)
- Write .cif file with values from a cif dict,
Only basic items are saved, rather than returning the orginal file
:param cifvals: dict from readcif
:param filename: filename to write (use None to return string)
:param comments: str comments to write to the file top matter
:return: None
- write_mcif(cifvals, filename=None, comments=None)
- Write magnetic .mcif file with values from a cif dict,
Only basic items are saved, rather than returning the original file
:param cifvals: dict from readcif
:param filename: filename to write (use None to return string)
:param comments: str comments to write to the file top matter
:return: None
- wyckoff_labels(spacegroup_dict, UVW)
- Return Wyckoff site labels for given positions
:param spacegroup_dict: spacegroup dict from tables, if magnetic spacegroup given, uses the parent spacegroup
:param UVW: n*3 array([u,v,w]) atomic positions in fractional coordinates
:return: list[n] of Wyckoff site letters
- xray_attenuation_length(elements, energy_kev, atom_per_volume, grazing_angle=90)
- Calcualte the attenuation length in microns
The depth into the material measured along the surface normal where the intensity of
x-rays falls to 1/e of its value at the surface.
A = sin(th) / n * mu
:param elements: str or list of str, if list - absorption will be summed over elements
:param energy_kev: float array
:param atom_per_volume: float atoms per A^3
:param grazing_angle: incidence angle relative to the surface, in degrees
:return: float or array in microns
- xray_dispersion_corrections(elements, energy_kev=None)
- Read xray dispersion corrections from atomic scattering factor table, giving f' and f" for different energies
From: http://henke.lbl.gov/optical_constants/asf.html
:param elements: list of str, name of element
:param energy_kev: float or list energy in keV (None to return original, uninterpolated list)
:return: f', f" with shape (len(energy), len(elements))
- xray_harmonic_rejection(elements, energy_kev, atom_per_volume, grazing_angle, harmonic=2)
- Calculate the specular reflectivity of a material
From: https://xdb.lbl.gov/Section4/Sec_4-2.html
:param elements: str or list of str, if list - absorption will be summed over elements
:param energy_kev: float array
:param atom_per_volume: float atoms per A^3
:param grazing_angle: incidence angle relative to the surface, in degrees
:param harmonic: int harmonic multiple
:return: float or array
- xray_reflectivity(elements, energy_kev, atom_per_volume, grazing_angle)
- Calculate the specular reflectivity of a material
From: https://xdb.lbl.gov/Section4/Sec_4-2.html
:param elements: str or list of str, if list - absorption will be summed over elements
:param energy_kev: float array
:param atom_per_volume: float atoms per A^3
:param grazing_angle: incidence angle relative to the surface, in degrees
:return: float or array
- xray_refractive_index(elements, energy_kev, atom_per_volume)
- Calculate the complex index of refraction of a material
n = 1 - (1/2pi)N*r0*lambda^2*(f1+if2) = 1 - Delta - iBeta
:param elements: str or list of str, if list atomic scattering factors will be summed over elements
:param energy_kev: float array
:param atom_per_volume: float atoms per A^3
:return: complex float or array
- xray_scattering_factor(element, Qmag=0)
- Read X-ray scattering factor table, calculate f(|Q|)
Uses the coefficients for analytical approximation to the scattering factors - ITC, p578 Table 6.1.1.4
Qff = xray_scattering_factor(element, Qmag=[0])
:param element: [n*str] list or array of elements
:param Qmag: [m] array of wavevector distance, in A^-1
:return: [m*n] array of scattering factors
- xray_scattering_factor_WaasKirf(element, Qmag=0)
- Read X-ray scattering factor table, calculate f(|Q|)
Uses the coefficients for analytical approximation to the scattering factors from:
"Waasmaier and Kirfel, Acta Cryst. (1995) A51, 416-431"
File from https://github.com/diffpy/libdiffpy/blob/master/src/runtime/f0_WaasKirf.dat
Qff = xray_scattering_factor_WaasKirf(element, Qmag=[0])
:param element: [n*str] list or array of elements
:param Qmag: [m] array of wavevector distance, in A^-1
:return: [m*n] array of scattering factors
- xray_scattering_factor_resonant(element, Qmag, energy_kev)
- Read X-ray scattering factor table, calculate f(|Q|)
Uses the coefficients for analytical approximation to the scattering factors - ITC, p578
Qff = xray_scattering_factor_resonant(element, energy_kev, qmag)
if resonant_energy = float(energy in keV), the total atomic scattering amplitude will be returned:
f(|Q|, E) = f0(|Q|) + f'(E) - if''(E)
See:
:param element: [n*str] list or array of elements
:param Qmag: [m] array wavevector distance |Q|, in A^-1
:param energy_kev: [o] array energy in keV
:return: [m*n*o] complex array of scattering factors
- xray_transmission(elements, energy_kev, atom_per_volume, distance_um)
- Calculate the transimssion of x-rays through a thick slab
T/T0 = exp(-n*mu*d)
:param elements: str or list of str, if list - absorption will be summed over elements
:param energy_kev: float array
:param atom_per_volume: float atoms per A^3
:param distance_um: float distance in microns
:return: float or array
|