Dans_Diffraction.functions_lattice (version 1.0.0)
index
c:\users\grp66007\onedrive - diamond light source ltd\pythonprojects\dans_diffraction\dans_diffraction\functions_lattice.py

Module: functions_lattice.py
 
By Dan Porter, PhD
Diamond
2024
 
 
Version 1.0
Last updated: 17/10/24
 
Version History:
17/10/24 1.0.0  Created module extracting lattice functions from functions_crystallography
 
Acknoledgements:
    October 2024    Thanks to Lee Richter for pointing out the error in triclinic angles!
 
@author: DGPorter

 
Modules
       
numpy

 
Functions
       
angles_allowed(alpha=90, beta=90, gamma=90)
Determine if lattice angles are suitable for basis vectors
 
https://journals.iucr.org/a/issues/2011/01/00/au5114/index.html
As reported in International Tables for Crystallography:
    Donnay & Donnay, 1959 International Tables for X-ray Crystallography, Vol. II.
    Koch, 2004 International Tables for Crystallography, Vol. C.
 
:param alpha: angle in degrees
:param beta: angle in degrees
:param gamma: angle in degrees
:return: bool, True if angles are suitable for creation of basis
basis2bandl(basis)
Calculate the Busing and Levy B matrix from a real space UV
"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*])
basis2latpar(basis_vectors)
Convert UV=[a,b,c] to a,b,c,alpha,beta,gamma
 a,b,c,alpha,beta,gamma = UV2latpar(UV)
 
:param basis_vectors: [3*3] basis vectors array [a[3], b[3], c[3]]
basis_1(*lattice_parameters, **kwargs)
Generate direct-space basis-vectors [a, b, c] from lattice parameters
Basis choice equivalent to that of materials project:
https://github.com/materialsproject/pymatgen/blob/v2024.10.3/src/pymatgen/core/lattice.py#L39-L1702
 
    vector c || z-axis
    vector a rotated by beta about y-axis from +ve x-axis
    vector b* || y-axis
 
Calculate the lattice positions:
 
    [[x, y, z]] = dot([[u, v, w]], [vec_a, vec_b, vec_c])
 
:param lattice_parameters: float or list in Angstroms & degrees, see gen_lattice_parameters()
:param kwargs: lattice parameters
:returns: [3x3] array, as [vec_a, vec_b, vec_c] in Angstroms
basis_2(*lattice_parameters, **kwargs)
Generate direct-space basis-vectors [a, b, c] from lattice parameters
Basis choice equivalent to that of Vesta:
https://github.com/materialsproject/pymatgen/blob/v2024.10.3/src/pymatgen/core/lattice.py#L39-L1702
 
    vector a || x-axis
    vector b rotated by gamma about z-axis from +ve y-axis
    vector c* || z-axis
 
Calculate the lattice positions:
 
    [[x, y, z]] = dot([[u, v, w]], [vec_a, vec_b, vec_c])
 
:param lattice_parameters: float or list in Angstroms & degrees, see gen_lattice_parameters()
:param kwargs: lattice parameters
:returns: [3x3] array, as [vec_a, vec_b, vec_c] in Angstroms
basis_3(*lattice_parameters, **kwargs)
Generate direct-space basis-vectors [a, b, c] from lattice parameters
Basis choice equivalent to the inverse of the Bmatrix of W. R. Busing and H. A. Levy, Acta Cryst. (1967)
https://docs.mantidproject.org/nightly/concepts/Lattice.html
 
    vector a* || x-axis
    vector b rotated by alpha about x-axis from +ve z-axis
    vector c || z-axis
 
Calculate the lattice positions:
 
    [[x, y, z]] = dot([[u, v, w]], [vec_a, vec_b, vec_c])
 
:param lattice_parameters: float or list in Angstroms & degrees, see gen_lattice_parameters()
:param kwargs: lattice parameters
:returns: [3x3] array, as [vec_a, vec_b, vec_c] in Angstroms
busingandlevy(*lattice_parameters, **kwargs)
Calculate the Busing and Levy B-matrix from lattice parameters
    "we 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
 
Creates a matrix to transform (hkl) into a cartesian basis:
    (qx,qy,qz)' = B.(h,k,l)'       (where ' indicates a column vector)
 
The B matrix is related to the reciprocal basis vectors:
    (astar, bstar, cstar) = 2 * np.pi * B.T
Where cstar is defined along the z-axis
 
:param lattice_parameters: float or list in Angstroms & degrees, see gen_lattice_parameters()
:param kwargs: lattice parameters
:returns: [3x3] array B matrix in inverse-Angstroms (no 2pi)
choose_basis(name)
Return a basis function based on a name
 
Available options:
    1. 'MaterialsProject': c || z, b* || y
    2. 'Vesta': a || x, c* || z
    3. 'BusingandLevy': c || z, a* || x, 'default'
 
:param name: str name of basis
:return: function
dspacing(h, k, l, *lattice_parameters, **kwargs)
Calculate the lattice d-spacing for Bragg reflection (h,k,l)
 
    d = lambda / 2 * sin(theta) = 2*pi / |h.a* + k.b* + l.c*|
 
:param h, k, l: Miller-indices of reflection
:param lattice_parameters: float or list in Angstroms & degrees, see gen_lattice_parameters()
:param kwargs: lattice parameters
:return: float in Angstroms
gen_lattice_parameters(*lattice_parameters, **kwargs)
Generate list of lattice parameters:
 a,b,c,alpha,beta,gamma = gen_lattice_parameters(*args)
args:
  1 -> a=b=c=1,alpha=beta=gamma=90
  [1,2,3] -> a=1,b=2,c=3,alpha=beta=gamma=90
  [1,2,3,120] -> a=1,b=2,c=3,alpha=beta=90,gamma=120
  [1,2,3,10,20,30] -> a=1,b=2,c=3,alpha=10,beta=20,gamma=30
  1,2,3,10,20,30 -> a=1,b=2,c=3,alpha=10,beta=20,gamma=30
  a=1,b=2,c=3,alpha=10,beta=20,gamma=30 -> a=1,b=2,c=3,alpha=10,beta=20,gamma=30
 
:param lattice_parameters: float or list in Angstroms & degrees
:param kwargs: lattice parameters
:return: a,b,c,alpha,beta,gamma
index_lattice(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
lattice_volume(*lattice_parameters, **kwargs)
Calculate basis volume from lattice parameters
 
    volume = vec_a . (vec_b X vec_c)
 
:param lattice_parameters: float or list in Angstroms & degrees, see gen_lattice_parameters()
:param kwargs: lattice parameters
:returns: float in Angstroms cubed
random_basis(symmetry='triclinic', basis_option='default')
Generate a random basis of unit vectors from a real set of lattice parameters
:param symmetry: string 'cubic', 'tetragona', 'rhobohedral', 'monoclinic-a/b/c', 'triclinic'
:param basis_option: str name of basis, 'materialsproject', 'vesta', 'busingandlevy'
:return: [3x3] array, as [vec_a, vec_b, vec_c] in Angstroms
random_lattice(symmetry='triclinic')
Return a random set of real lattice parameters
:param symmetry: string 'cubic', 'tetragona', 'rhobohedral', 'monoclinic-a/b/c', 'triclinic'
:return: (a, b, c, alpha, beta, gamma) lattice parameters in Angstroms/ degrees
reciprocal_basis(basis_vectors)
Return the reciprocal basis vectors
    [a*, b*, c*] = 2*pi*inv([a, b, c]).T
 
:param basis_vectors: [3*3] basis vectors array [a[3], b[3], c[3]]
:return: [3*3] array of reciprocal vectors [a*[3], b*[3], c*[3]]
reciprocal_lattice_parameters(*lattice_parameters, **kwargs)
Return the reciprocal lattice parameters in inverse-angstroms and degrees
:param lattice_parameters: float or list in Angstroms & degrees, see gen_lattice_parameters()
:param kwargs: lattice parameters
:return: a*, b*, c*, alpha*, beta*, gamma*