77Diamond
882017
99
10- Version 2.3.4
11- Last updated: 17/05 /24
10+ Version 2.3.5
11+ Last updated: 23/12 /24
1212
1313Version History:
141410/09/17 0.1 Program created
404015/05/24 2.3.4 Added "save" and "load" methods to structure factor calculation, improved powder for large calculations
414116/05/24 2.3.4 Added printed progress bar to generate_intensity_cut during convolusion
424217/05/24 2.3.4 Changed generate_intensity_cut to make it much faster
43+ 23/12/24 2.3.5 Added polarised neutron options
4344
4445@author: DGPorter
4546"""
5354from . import multiple_scattering as ms
5455# from . import tensor_scattering as ts # Removed V1.7
5556
56- __version__ = '2.3.4'
57- __scattering_types__ = {'xray' : ['xray' , 'x' , 'x-ray' , 'thomson' , 'charge' ],
58- 'neutron' : ['neutron' , 'n' , 'nuclear' ],
59- 'xray magnetic' : ['xray magnetic' , 'magnetic xray' , 'spin xray' , 'xray spin' ],
60- 'neutron magnetic' : ['neutron magnetic' , 'magnetic neutron' , 'magnetic' ],
61- 'xray resonant' : ['xray resonant' , 'resonant' , 'resonant xray' , 'rxs' ],
62- 'xray dispersion' : ['dispersion' , 'xray dispersion' ]}
57+ __version__ = '2.3.5'
6358
6459
6560class Scattering :
@@ -119,14 +114,14 @@ class Scattering:
119114 # Polarisation Options
120115 _polarised = False
121116 _polarisation = 'sp'
122- _polarisation_vector_incident = [ 0 , 1 , 0 ]
117+ _polarisation_vector_incident = ( 0 , 1 , 0 )
123118
124119 # Radiation energy
125120 _energy_kev = fg .Cu
126121
127122 # Resonant X-ray Options
128123 _azimuthal_angle = 0
129- _azimuthal_reference = [1 ,0 , 0 ]
124+ _azimuthal_reference = [1 , 0 , 0 ]
130125 _resonant_flm = (0 , 1 , 0 )
131126 _resonant_approximation_e1e1 = True
132127 _resonant_approximation_e2e2 = False
@@ -137,7 +132,7 @@ def __init__(self, xtl):
137132 self .xtl = xtl
138133
139134 # Initialise the scattering type container
140- self .Type = ScatteringTypes (self , __scattering_types__ )
135+ self .Type = ScatteringTypes (self , fs . SCATTERING_TYPES )
141136
142137 def __repr__ (self ):
143138 return 'Scattering(%s, %s)' % (self .xtl .name , self ._scattering_type )
@@ -195,7 +190,7 @@ def setup_scatter(self, scattering_type=None, energy_kev=None, wavelength_a=None
195190 """
196191 Simple way to set scattering parameters, each parameter is internal to xtl (self)
197192
198- scattering_type: self._scattering type : 'xray','neutron','xray magnetic','neutron magnetic','xray resonant', 'xray dispersion'
193+ scattering_type: self._scattering type : 'xray','neutron','xray magnetic','neutron magnetic','xray resonant', 'xray dispersion', 'neutron polarised', 'xray polarised'
199194 energy_kev : self._energy_kev : radiation energy in keV
200195 wavelength_a: self._wavelength_a : radiation wavelength in Angstrom
201196 powder_units: self._powder_units : units to use when displaying/ plotting ['twotheta', 'd',' 'q']
@@ -379,9 +374,11 @@ def structure_factor(self, hkl=None, scattering_type=None, int_hkl=True, **kwarg
379374 'xray' - uses x-ray form factors
380375 'neutron' - uses neutron scattering lengths
381376 'xray magnetic' - calculates the magnetic (non-resonant) component of the x-ray scattering
382- 'neutron magnetic' - calculates the magnetic component of neutron scattering
377+ 'neutron magnetic' - calculates the magnetic component of neutron scattering with average polarisation
383378 'xray resonant' - calculates magnetic resonant scattering
384379 'xray dispersion' - uses x-ray form factors including f'-if'' components
380+ 'neutron polarised' - calcualtes magnetic component with incident polarised neutrons
381+ 'xray polarised' - calcualtes magnetic component with incident polarised x-rays
385382
386383 Notes:
387384 - Uses x-ray atomic form factors, calculated from approximated tables in the ITC
@@ -1088,7 +1085,7 @@ def magnetic_neutron(self, HKL):
10881085 # Calculate intensity
10891086 I = SF * np .conj (SF )
10901087 return np .real (I )
1091-
1088+
10921089 def xray_magnetic (self , HKL ):
10931090 """
10941091 Calculate the non-resonant magnetic component of the structure factor
@@ -1102,51 +1099,53 @@ def xray_magnetic(self, HKL):
11021099 No orbital component assumed
11031100 magnetic moments assumed to be in the same reference frame as the polarisation
11041101 """
1105-
1106- HKL = np .asarray (np .rint (HKL ),dtype = float ).reshape ([- 1 ,3 ])
1102+
1103+ HKL = np .asarray (np .rint (HKL ), dtype = float ).reshape ([- 1 , 3 ])
11071104 Nref = len (HKL )
1108-
1109- uvw ,type ,label ,occ ,uiso ,mxmymz = self .xtl .Structure .get ()
1105+
1106+ uvw , type , label , occ , uiso , mxmymz = self .xtl .Structure .get ()
11101107 Nat = len (uvw )
1111-
1108+
11121109 Qmag = self .xtl .Cell .Qmag (HKL )
1113-
1110+
11141111 # Get magnetic form factors
11151112 if self ._use_magnetic_form_factor :
1116- ff = fc .magnetic_form_factor (type ,Qmag )
1113+ ff = fc .magnetic_form_factor (type , Qmag )
11171114 else :
1118- ff = np .ones ([len (HKL ),Nat ])
1119-
1115+ ff = np .ones ([len (HKL ), Nat ])
1116+
11201117 # Calculate moment
1121- momentmag = fg .mag (mxmymz ).reshape ([- 1 ,1 ])
1122- momentxyz = self .xtl .Cell .calculateR (mxmymz ) # moment direction in cartesian reference frame
1123- moment = momentmag * fg .norm (momentxyz ) # broadcast n*1 x n*3 = n*3
1118+ momentmag = fg .mag (mxmymz ).reshape ([- 1 , 1 ])
1119+ momentxyz = self .xtl .Cell .calculateR (mxmymz ) # moment direction in cartesian reference frame
1120+ moment = momentmag * fg .norm (momentxyz ) # broadcast n*1 x n*3 = n*3
11241121 moment [np .isnan (moment )] = 0.
1125-
1122+
11261123 # Calculate dot product
1127- dot_KR = np .dot (HKL ,uvw .T )
1128-
1124+ dot_KR = np .dot (HKL , uvw .T )
1125+
11291126 # Calculate structure factor
1130- SF = np .zeros (Nref ,dtype = complex )
1127+ SF = np .zeros (Nref , dtype = complex )
11311128 for n in range (Nref ):
11321129 # Calculate vector structure factor
1133- SFm = [0. ,0. ,0. ]
1134- for m ,mom in enumerate (moment ):
1135- SFm = SFm + ff [n ,m ] * np .exp (1j * 2 * np .pi * dot_KR [n ,m ])* mom
1136-
1130+ SFm = [0. , 0. , 0. ]
1131+ for m , mom in enumerate (moment ):
1132+ SFm = SFm + ff [n , m ] * np .exp (1j * 2 * np .pi * dot_KR [n , m ]) * mom
1133+
11371134 # Calculate polarisation with incident x-ray
11381135 # The reference frame of the x-ray and the crystal are assumed to be the same
11391136 # i.e. pol=[1,0,0] || mom=[1,0,0] || (1,0,0)
11401137 if self ._polarised :
1141- SF [n ] = np .dot (SFm ,self ._polarisation_vector_incident )
1138+ SF [n ] = np .dot (SFm , self ._polarisation_vector_incident )
11421139 else :
1143- #SF[n] = np.dot(SFm,SFm) # maximum possible
1144- SF [n ] = (np .dot (SFm ,[1 ,0 ,0 ]) + np .dot (SFm ,[0 ,1 ,0 ]) + np .dot (SFm ,[0 ,0 ,1 ]))/ 3 # average polarisation
1145-
1146- SF = SF / self .xtl .scale
1147-
1140+ # SF[n] = np.dot(SFm,SFm) # maximum possible
1141+ SF [n ] = (
1142+ np .dot (SFm , [1 , 0 , 0 ]) + np .dot (SFm , [0 , 1 , 0 ]) + np .dot (SFm , [0 , 0 , 1 ])
1143+ ) / 3 # average polarisation
1144+
1145+ SF = SF / self .xtl .scale
1146+
11481147 if self ._return_structure_factor : return SF
1149-
1148+
11501149 # Calculate intensity
11511150 I = SF * np .conj (SF )
11521151 return np .real (I )
@@ -1207,7 +1206,7 @@ def xray_resonant(self, HKL, energy_kev=None, polarisation='sp', F0=1, F1=1, F2=
12071206
12081207 # Calculate structure factor
12091208 # Broadcasting used on 2D fxres
1210- SF [:,psival ] = np .sum (fxres * dw * occ * np .exp (1j * 2 * np .pi * dot_KR ),axis = 1 )
1209+ SF [:, psival ] = np .sum (fxres * dw * occ * np .exp (1j * 2 * np .pi * dot_KR ), axis = 1 )
12111210
12121211 SF = SF / self .xtl .scale
12131212
0 commit comments