Dans_Diffraction.tensor_scattering (version 1.0)
index
c:\users\dgpor\onedrive - diamond light source ltd\pythonprojects\dans_diffraction\dans_diffraction\tensor_scattering.py

Tensor Scattering code, By Prof. Steve Collins
Based on code available at: https://github.com/spc93/tensor-scattering-calculation
 
Example:
    xtl = dif.Crystal('ZnO.cif')
    t = TensorScatteringClass(xtl, Site='Zn1', TimeEven=False)
    t.PlotIntensityInPolarizationChannels('E1E2', lam=12.4/9.659, hkl=np.array([1,1,5]), hkln=np.array([1,0,0]), K=3, Time=1, Parity=-1, mk=None, sk=None, sigmapi='sigma')
    t.print_tensors()
 
Created from python package "TensorScatteringClass.py"
Version 1.0
17/02/2020
 
 Proffesor Steve Collins, steve.collins@diamond.ac.uk Tel: +44 1235 778087
 www.diamond.ac.uk
 Diamond Light Source, Chilton, Didcot, Oxon, OX11 0DE, U.K.

 
Modules
       
numpy
matplotlib.pyplot
pprint
sys

 
Classes
       
builtins.object
TensorScatteringClass
TensorScatteringClassMagrotExtension

 
class TensorScatteringClass(builtins.object)
    TensorScatteringClass(xtl, Site, TimeEven=False)
 
Python class for resonant tensor scattering.
 
xtl = dif.Crystal('ZnO.cif')
t = TensorScatteringClass(xtl, Site='Zn1', TimeEven=False)
t.PlotIntensityInPolarizationChannels('E1E2', lam=12.4/9.659, hkl=np.array([1,1,5]), hkln=np.array([1,0,0]), K=3, Time=1, Parity=-1, mk=None, sk=None, sigmapi='sigma')
print(t.print_tensors())
 
While this currently has limited capability for magnetic systems, magnetic symmetry operators are used throughout
If no Site keyword arg supplied then available sites will be displayed before exiting
Useful methods:
    latt2b          compute reciprocal or real-space B matrix from lattice
    equiv_sites     compute symmetry-equivalent sites for selected site
    invert          inverts current spacegroup operators and sites
    isGroup(sg)     Returns True if sg forms a group or False and shows message if not (self.isGroup(self.sglist) should return True)
    TensorCalc      Calculate tensor properties for crystal and reflection; save tensors as attributes; print tensor information
    print_tensors() Display crystal/atomic/structure factor spherical/Cartesian tensors
    CalculateIntensityInPolarizationChannels    calculate four intensity channels vs psi
    PlotIntensityInPolarizationChannels        plot sigma or pi intensity vs azimuthal angle
    
Useful parameters:
    lattice
    B
    sglist
    pglist
    crystalpglist
    Ts_crystal, Ts_atom, Fs (spherical tensors)
    Tc_crystal, Tc_atom, Fc (spherical tensors)
 
  Methods defined here:
CalculateIntensityFromPolarizationAnalyser(self, process, lam, hkl, hkln, psideg, pol_eta_deg, pol_th_deg=45, stokesvec_swl=[0, 0, 1], K=None, Time=None, Parity=None, mk=None, lk=None, sk=None)
process = 'Scalar', 'E1E1', 'E1E2', 'E2E2', 'E1E1mag', 'NonResMag'
Calculate intensity from polarization analyser vs pol_eta (analyser rotation)
pol_eta_deg can be a scalar or array/list
pol_th_deg is polarizer theta angle (deg) (default 45)
stokesvec_swl is Stokes as per SWL papers (P3 = horizontal linear, default [0 ,0, 1])
CalculateIntensityInPolarizationChannels(self, process, lam, hkl, hkln, psideg, K=None, Time=None, Parity=None, mk=None, lk=None, sk=None)
process = 'Scalar', 'E1E1', 'E1E2', 'E2E2', 'E1E1mag', 'NonResMag'
Calculate intensity in four linear polarization channels
psi can be a scalar or array/list
PlotIntensityInPolarizationChannels(self, process, lam, hkl, hkln, psideg=None, K=None, Time=None, Parity=None, mk=None, lk=None, sk=None, sigmapi=None, savefile=None)
Plot azimuthal dependence of sigma or pi intensity and save figure if savefile keyword string (fine name root) given
PlotIntensityVsPolarizationAnalyserRotation(self, process, lam, hkl, hkln, psideg, pol_eta_deg, pol_th_deg=45, stokesvec_swl=[0, 0, 1], K=None, Time=None, Parity=None, mk=None, lk=None, sk=None, savefile=None)
Plot intensity vs PA rotation and save figure if savefile keyword string (fine name root) given
TensorCalc(self, hkl=array([0, 0, 0]), K=None, Parity=1, Time=1)
hkl, hkln:   hkl values for reflection and azimuthal reference
returns: Ts, Tc1, Tc_atom, Tc_crystal, Ts_atom, Ts_crystal, Fc, Fs
Ts          Calcualted spherical tensor
Tc1         Calculated cartesian tensor
Tc_atom     Atomic cartesian tensor
Tc_crystal  Crystal cartesian tensor
Ts_atom     Atomic spherical tensor
Ts_crystal  Crystal spherical tensor
Fc          SF Crystal tensor
Fs          SF spherical tensor
__init__(self, xtl, Site, TimeEven=False)
Initialize self.  See help(type(self)) for accurate signature.
__repr__(self)
Return repr(self).
info(self)
invert(self)
self.invert()
inverts current spacegroup operators and sites
print_tensors(self)

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
class TensorScatteringClassMagrotExtension(TensorScatteringClass)
    TensorScatteringClassMagrotExtension(xtl, Site, TimeEven=False)
 
Python class for resonant tensor scattering.
 
xtl = dif.Crystal('ZnO.cif')
t = TensorScatteringClass(xtl, Site='Zn1', TimeEven=False)
t.PlotIntensityInPolarizationChannels('E1E2', lam=12.4/9.659, hkl=np.array([1,1,5]), hkln=np.array([1,0,0]), K=3, Time=1, Parity=-1, mk=None, sk=None, sigmapi='sigma')
print(t.print_tensors())
 
While this currently has limited capability for magnetic systems, magnetic symmetry operators are used throughout
If no Site keyword arg supplied then available sites will be displayed before exiting
Useful methods:
    latt2b          compute reciprocal or real-space B matrix from lattice
    equiv_sites     compute symmetry-equivalent sites for selected site
    invert          inverts current spacegroup operators and sites
    isGroup(sg)     Returns True if sg forms a group or False and shows message if not (self.isGroup(self.sglist) should return True)
    TensorCalc      Calculate tensor properties for crystal and reflection; save tensors as attributes; print tensor information
    print_tensors() Display crystal/atomic/structure factor spherical/Cartesian tensors
    CalculateIntensityInPolarizationChannels    calculate four intensity channels vs psi
    PlotIntensityInPolarizationChannels        plot sigma or pi intensity vs azimuthal angle
    
Useful parameters:
    lattice
    B
    sglist
    pglist
    crystalpglist
    Ts_crystal, Ts_atom, Fs (spherical tensors)
    Tc_crystal, Tc_atom, Fc (spherical tensors)
 
 
Method resolution order:
TensorScatteringClassMagrotExtension
TensorScatteringClass
builtins.object

Methods defined here:
PlotIntensityInPolarizationChannelsVsMagrot(self, process, lam, hkl, hkln, psideg=None, K=None, Time=None, Parity=None, mk=None, lk=None, sk=None, sigmapi=None, savefile=None)
Extension of TensorScatteringClass with new method to calculate magnetic scattering vs magnet rotation angle
Moments are rotated about z axis
psideg must be a scalar
Plot magrot dependence of sigma or pi intensity and save figure if savefile keyword string (fine name root) given

Methods inherited from TensorScatteringClass:
CalculateIntensityFromPolarizationAnalyser(self, process, lam, hkl, hkln, psideg, pol_eta_deg, pol_th_deg=45, stokesvec_swl=[0, 0, 1], K=None, Time=None, Parity=None, mk=None, lk=None, sk=None)
process = 'Scalar', 'E1E1', 'E1E2', 'E2E2', 'E1E1mag', 'NonResMag'
Calculate intensity from polarization analyser vs pol_eta (analyser rotation)
pol_eta_deg can be a scalar or array/list
pol_th_deg is polarizer theta angle (deg) (default 45)
stokesvec_swl is Stokes as per SWL papers (P3 = horizontal linear, default [0 ,0, 1])
CalculateIntensityInPolarizationChannels(self, process, lam, hkl, hkln, psideg, K=None, Time=None, Parity=None, mk=None, lk=None, sk=None)
process = 'Scalar', 'E1E1', 'E1E2', 'E2E2', 'E1E1mag', 'NonResMag'
Calculate intensity in four linear polarization channels
psi can be a scalar or array/list
PlotIntensityInPolarizationChannels(self, process, lam, hkl, hkln, psideg=None, K=None, Time=None, Parity=None, mk=None, lk=None, sk=None, sigmapi=None, savefile=None)
Plot azimuthal dependence of sigma or pi intensity and save figure if savefile keyword string (fine name root) given
PlotIntensityVsPolarizationAnalyserRotation(self, process, lam, hkl, hkln, psideg, pol_eta_deg, pol_th_deg=45, stokesvec_swl=[0, 0, 1], K=None, Time=None, Parity=None, mk=None, lk=None, sk=None, savefile=None)
Plot intensity vs PA rotation and save figure if savefile keyword string (fine name root) given
TensorCalc(self, hkl=array([0, 0, 0]), K=None, Parity=1, Time=1)
hkl, hkln:   hkl values for reflection and azimuthal reference
returns: Ts, Tc1, Tc_atom, Tc_crystal, Ts_atom, Ts_crystal, Fc, Fs
Ts          Calcualted spherical tensor
Tc1         Calculated cartesian tensor
Tc_atom     Atomic cartesian tensor
Tc_crystal  Crystal cartesian tensor
Ts_atom     Atomic spherical tensor
Ts_crystal  Crystal spherical tensor
Fc          SF Crystal tensor
Fs          SF spherical tensor
__init__(self, xtl, Site, TimeEven=False)
Initialize self.  See help(type(self)) for accurate signature.
__repr__(self)
Return repr(self).
info(self)
invert(self)
self.invert()
inverts current spacegroup operators and sites
print_tensors(self)

Data descriptors inherited from TensorScatteringClass:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

 
Functions
       
CalculateIntensityFromPolarizationAnalyser(process, B, sitevec, sglist, lam, hkl, hkln, psideg, pol_eta_deg, pol_th_deg=45, stokesvec_swl=[0, 0, 1], K=None, Time=None, Parity=None, mk=None, lk=None, sk=None)
process = 'Scalar', 'E1E1', 'E1E2', 'E2E2', 'E1E1mag', 'NonResMag'
Calculate intensity from polarization analyser vs pol_eta (analyser rotation)
pol_eta_deg can be a scalar or array/list
pol_th_deg is polarizer theta angle (deg) (default 45)
stokesvec_swl is Stokes as per SWL papers (P3 = horizontal linear, default [0 ,0, 1])
CalculateIntensityInPolarizationChannels(process, B, sitevec, sglist, lam, hkl, hkln, psideg, K=None, Time=None, Parity=None, mk=None, lk=None, sk=None)
process = 'Scalar', 'E1E1', 'E1E2', 'E2E2', 'E1E1mag', 'NonResMag'
Calculate intensity in four linear polarization channels
psi can be a scalar or array/list
ClebschGordan(j1, j2, m1, m2, J, M, warn=True)
ClebschGordan(j1, j2, m1, m2, J, M, cglimit=20,warn=True)
Computes exact sympy form for Clebsch-Gordan coefficient
<j1 j2; m1 m2|j1 j2; JM>.
For reference see
http://en.wikipedia.org/wiki/Table_of_Clebsch-Gordan_coefficients.
Clebsch Gordan numpy function by Michael V. DePalatis, modified and converted to sympy by SPC
warn gives warning for unphysical coefficients
 Adapted from sympy ClebschGordan
E1E1ResonantMagneticScatteringMatrix(mk, esig_c, e0pi_c, e1pi_c, q0_c, q1_c)
Calculate 2x2 scattering amplitude matrix for E1E1 resonant magnetic scattering
NonResonantMagneticScatteringMatrix(sk, lk, esig_c, e0pi_c, e1pi_c, q0_c, q1_c)
Calculate 2x2 scattering amplitude matrix for non-resonant magnetic scattering
spin and orbital components (Complex) for reflection are sk, lk
BB and AA are B (spin) and A (orbit) coupling vectors from SWL, Blume etc
StoneCoefficients(CouplingSequenceList, k=(-0-1j))
StoneCoefficients(CouplingSequenceList,k=phase_convention)
Sympy Spherical-Cartesian conversion coefficients from
A.J. Stone Molecular Physics 29 1461 (1975) (Equation 1.9)
CouplingSequenceList is the coupling sequence for spherical tensors,
    each time coupling to a new vector to form a tensor of given rank
    (sequence always starts with 1)
k=-I for Condon & Shortley phase convention (default) of k=1 for Racah
e.g. StoneCoefficients([1,2,3]) returns conversion coefficients for K=3, coupling with
maximum rank and Condon & Shortley (default) phase convention
Example:     C123=StoneCoefficients([1,2,3])    returns conversion matrix for coupling sequence 123 (K=3)
        print(lcontract(C123,3,[1,0,0,0,0,0,0])) returns table values for Q=-3
Numpy version converted from, Sympy version
StoneCoupleVector(Cold, Knew, C1)
StoneCoupleVector(Cold,Knew,C1)
couple Stone coefficients Cold to a new vector to make coefficient for spherocal tensor of rank Knew
using vector coupling coefficients C1
A.J. Stone Molecular Physics 29 1461 (1975) (Equation 1.9)
Numpy version converted from Sympy version
StoneSphericalToCartConversionCoefs(K, Calc=True, k=(-0-1j))
Condon&Shortley phase convention (k=-i in Stone's paper)
from FortranForm (No - CForm?) First List->array, del other lists,spaces, extra bracket around first level
If Calc==False then use these expressions from Mathematica, else calculate them numerically
TensorScatteringMatrix(mpol, Fs, time, parity, esig_c, e0pi_c, e1pi_c, q0_c, q1_c)
Calculate 2x2 scattering amplitude matrix for tensor scattering
apply_sym(Tensor, symop_list, Bmat=array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), P=None, T=1)
apply point sym ops in symop_list to tensor of rank K
Optional Bmat is used to transform arrays to Cartesian from crystal basis
Default time (T) sym +1; no default for parity (P)
calc_sf(Tensor, R, hkl, spacegroup_list, Bmat=array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), P=None, T=1)
calc structure factor tensor for symop_list to tensot T of rank K at position R hkl=Q
Optional Bmat is used to transform arrays to Cartesian from crystal basis
calculatescatteringmatrix(process, B, lam, psival, hkl, hkln, Fs, Time=None, Parity=None, mk=None, sk=None, lk=None)
Calculate G for specified scattering process; require B, lam, psival, hkl, hkln
process = 'Scalar', 'E1E1', 'E1E2', 'E2E2', 'E1E1mag', 'NonResMag'
Fs (structure factor spherical tensor), Time & Parity symmetry, mk, sk, lk are required for specific processes only
2 x 2 G matrix defined in SWL papers
calcxrayvectors(B, lam, psi, hkl, hkln)
calculate relevant Cartesian vector in sample reference frame
return(h, q0, q1, esig, e0pi, e1pi)
caltheta(B, lam, hkl)
Calculate Bragg angle theta
:param B: B matrix
:param lam: wavelength in A
:param hkl: [hkl]
:return: float: angle in deg
cart_to_spherical_tensor(Tc)
crystal_point_sym(spacegroup_list)
crystal_to_cart_operator(S, B)
equiv_sites(spacegroup_list, sitevec)
equiv_sites(spacegroup_list, sitevec)
returns symmetry-equivalent sites for selected site
firstCell(V)
genpos2matvec(gen_pos_string)
convert general position string to vector/matrix form (floats) using lists as row vectors
indexlist(shape)
indexlist(shape)
create a list of index lists covering all indices for shape list (all possible indices)
  (Numpy 1.6 has new indexing functionality that my render this obsolete)
isGroup(G)
Tests if G is a group
:param G: is a list of [mat, vec, timescalar]
:return: Boolean
latt2b(lat, direct=False, BLstyle=False)
follow Busing&Levy, D.E.Sands
direct=False: normal recip space B matrix (B&L)
direct=True, BLstyle=True: Busing & Levy style applied to real space (i.e. x||a)
direct=True, BLstyle=False: Real space B matrix compatible with recip space B matrix
msg(num, txt=['plus', 'minus', 'zero', 'other'])
return message text for +1,-1, 0, other (e.g. None)
norm_array(Array, Minval=0.001)
Normalise array by largest abs value if >Minval (avoids trying to renormalise zero array)
print_tensors(B, sitevec, sglist, hkl=array([0, 0, 0]), K=None, Parity=1, Time=1)
return str of tensors
rand(...) method of numpy.random.mtrand.RandomState instance
rand(d0, d1, ..., dn)
 
Random values in a given shape.
 
.. note::
    This is a convenience function for users porting code from Matlab,
    and wraps `random_sample`. That function takes a
    tuple to specify the size of the output, which is consistent with
    other NumPy functions like `numpy.zeros` and `numpy.ones`.
 
Create an array of the given shape and populate it with
random samples from a uniform distribution
over ``[0, 1)``.
 
Parameters
----------
d0, d1, ..., dn : int, optional
    The dimensions of the returned array, must be non-negative.
    If no argument is given a single Python float is returned.
 
Returns
-------
out : ndarray, shape ``(d0, d1, ..., dn)``
    Random values.
 
See Also
--------
random
 
Examples
--------
>>> np.random.rand(3,2)
array([[ 0.14022471,  0.96360618],  #random
       [ 0.37601032,  0.25528411],  #random
       [ 0.49313049,  0.94909878]]) #random
scalar_contract(X, T)
sf_symmetry(R, hkl, spacegroup_list)
analyse symmetry of any possible structure factor (mainly for information)
returns [sym_phases, gen_scalar_allowed, site_scalar_allowed, tensor_allowed, Psym, Tsym, PTsym]
site_sym(spacegroup_list, sitevec)
spacegroup_list_from_genpos_list(genposlist)
spherical_to_cart_tensor(Ts)
symmetry_str(R, hkl, spacegroup_list)
analyse symmetry of any possible structure factor (mainly for information)
returns str
tensorcalc(B, sitevec, sglist, hkl=array([0, 0, 0]), K=None, Parity=1, Time=1)
calculate scatterin tensor
B = B matrix
sitevec = [u,v,w]
sglist = list of symmetries
hkl, hkln:   hkl values for reflection and azimuthal reference
K = tensor rank
Parity = +/- 1
Time = +/- 1
returns: Ts, Tc1, Tc_atom, Tc_crystal, Ts_atom, Ts_crystal, Fc, Fs
Ts          Calcualted spherical tensor
Tc1         Calculated cartesian tensor
Tc_atom     Atomic cartesian tensor
Tc_crystal  Crystal cartesian tensor
Ts_atom     Atomic spherical tensor
Ts_crystal  Crystal spherical tensor
Fc          SF Crystal tensor
Fs          SF spherical tensor
tensorproperties(sitevec, sglist, hkl=array([0, 0, 0]), Parity=1, Time=1)
Return tensor properties
sitevec = [u,v,w]
sglist = list of symmetries
hkl, hkln:   hkl values for reflection and azimuthal reference
returns: Ts, Tc1, Tc_atom, Tc_crystal, Ts_atom, Ts_crystal, Fc, Fs
Ts          Calcualted spherical tensor
Tc1         Calculated cartesian tensor
Tc_atom     Atomic cartesian tensor
Tc_crystal  Crystal cartesian tensor
Ts_atom     Atomic spherical tensor
Ts_crystal  Crystal spherical tensor
Fc          SF Crystal tensor
Fs          SF spherical tensor
theta_to_cartesian(hkl, hkln, psi, B)
Unitary matrix for transformation from theta to cartesian coordinate system
transform_cart(T, S, P=0)
#transform Cart tensor rank K using symmetry operator S
#If optional parameter P (parity) is given then a correction is made to account for the otherwise incorrect
#tranformation of Cartesian tensors derived from spherical pseudotensors (see Mittelwihr paper)
xtensor(process, rank, time, parity, e0, e1, q0, q1)
Calculates resonant scattering tensor as per Lovesey
This version is a dump of the output of a Mathematica implementation (hence messy!)
The Sympy version of this calculation carries out the same tensor calculation

 
Data
        FMT = '\n%28s: '