0
# X-ray Scattering
1
2
X-ray scattering factor calculations, scattering length densities, form factors, and optical properties including refractive indices and mirror reflectivity for crystallographic and materials science applications.
3
4
## Capabilities
5
6
### Scattering Length Density Calculations
7
8
Calculate X-ray scattering length densities for materials, fundamental for X-ray reflectometry, small-angle X-ray scattering, and grazing incidence techniques.
9
10
```python { .api }
11
def xray_sld(compound, density: float = None, energy: float = None,
12
wavelength: float = None) -> tuple:
13
"""
14
Calculate X-ray scattering length density for a compound.
15
16
Args:
17
compound: Formula string, Formula object, or atomic composition
18
density: Mass density in g/cm³ (uses compound.density if available)
19
energy: X-ray energy in keV
20
wavelength: X-ray wavelength in Ångström (alternative to energy)
21
22
Returns:
23
tuple: (sld_real, sld_imag) in units of 10⁻⁶ Ų⁻²
24
sld_real: Real scattering length density (dispersion)
25
sld_imag: Imaginary scattering length density (absorption)
26
"""
27
28
def xray_sld_from_atoms(atoms: dict, density: float, energy: float = None,
29
wavelength: float = None) -> tuple:
30
"""
31
Low-level SLD calculation from atomic composition.
32
33
Args:
34
atoms: Dictionary mapping atoms to counts
35
density: Mass density in g/cm³
36
energy: X-ray energy in keV
37
wavelength: X-ray wavelength in Ångström
38
39
Returns:
40
tuple: (sld_real, sld_imag) in 10⁻⁶ Ų⁻² units
41
"""
42
```
43
44
Usage examples:
45
46
```python
47
import periodictable as pt
48
49
# Simple compounds at Cu K-alpha (8.048 keV)
50
water = pt.formula("H2O", density=1.0)
51
sld_real, sld_imag = pt.xray_sld(water, energy=8.048)
52
print(f"H2O SLD at Cu K-alpha: {sld_real:.4f} + {sld_imag:.4f}i (10⁻⁶ Ų⁻²)")
53
54
# Different X-ray energies
55
energies = [8.048, 17.479, 21.0] # Cu K-alpha, Mo K-alpha, arbitrary
56
names = ["Cu K-alpha", "Mo K-alpha", "21 keV"]
57
58
for energy, name in zip(energies, names):
59
sld = pt.xray_sld(water, energy=energy)
60
print(f"H2O at {name}: {sld[0]:.4f} + {sld[1]:.4f}i")
61
62
# Using wavelength instead of energy
63
lambda_cu = 1.5418 # Å, Cu K-alpha
64
sld_wl = pt.xray_sld(water, wavelength=lambda_cu)
65
print(f"H2O at {lambda_cu} Å: {sld_wl[0]:.4f} + {sld_wl[1]:.4f}i")
66
67
# Complex materials
68
silicon = pt.formula("Si", density=2.33)
69
sio2 = pt.formula("SiO2", density=2.20)
70
71
si_sld = pt.xray_sld(silicon, energy=8.048)
72
sio2_sld = pt.xray_sld(sio2, energy=8.048)
73
74
print(f"Si SLD: {si_sld[0]:.4f} + {si_sld[1]:.4f}i")
75
print(f"SiO2 SLD: {sio2_sld[0]:.4f} + {sio2_sld[1]:.4f}i")
76
print(f"Contrast: {si_sld[0] - sio2_sld[0]:.4f}")
77
```
78
79
### Wavelength and Energy Conversions
80
81
Convert between X-ray wavelength and energy for different X-ray sources and experimental conditions.
82
83
```python { .api }
84
def xray_wavelength(energy: float) -> float:
85
"""
86
Convert X-ray energy to wavelength.
87
88
Args:
89
energy: X-ray energy in keV
90
91
Returns:
92
Wavelength in Ångström
93
"""
94
95
def xray_energy(wavelength: float) -> float:
96
"""
97
Convert X-ray wavelength to energy.
98
99
Args:
100
wavelength: X-ray wavelength in Ångström
101
102
Returns:
103
Energy in keV
104
"""
105
```
106
107
Usage examples:
108
109
```python
110
import periodictable.xsf as xsf
111
112
# Common X-ray sources
113
sources = [
114
("Cu K-alpha", 8.048),
115
("Mo K-alpha", 17.479),
116
("Ag K-alpha", 22.163),
117
("Cr K-alpha", 5.417)
118
]
119
120
print("X-ray source wavelengths:")
121
for name, energy in sources:
122
wavelength = xsf.xray_wavelength(energy)
123
print(f"{name}: {energy} keV = {wavelength:.4f} Å")
124
125
# Synchrotron energies
126
synchrotron_energies = [6, 8, 10, 12, 15, 20] # keV
127
print("\nSynchrotron wavelengths:")
128
for energy in synchrotron_energies:
129
wavelength = xsf.xray_wavelength(energy)
130
print(f"{energy:2d} keV = {wavelength:.4f} Å")
131
132
# Convert wavelengths back to energies
133
wavelengths = [1.5418, 0.7107, 0.5594] # Cu, Mo, Ag K-alpha
134
print("\nWavelength to energy:")
135
for wl in wavelengths:
136
energy = xsf.xray_energy(wl)
137
print(f"{wl:.4f} Å = {energy:.3f} keV")
138
```
139
140
### Optical Properties
141
142
Calculate refractive indices and optical properties from scattering length densities for X-ray optics applications.
143
144
```python { .api }
145
def index_of_refraction(compound, density: float = None,
146
energy: float = None, wavelength: float = None) -> complex:
147
"""
148
Calculate complex refractive index from SLD.
149
150
Args:
151
compound: Formula string, Formula object, or atomic composition
152
density: Mass density in g/cm³
153
energy: X-ray energy in keV
154
wavelength: X-ray wavelength in Ångström
155
156
Returns:
157
complex: n = 1 - δ - iβ where δ,β are dispersion and absorption
158
"""
159
160
def mirror_reflectivity(compound, density: float = None,
161
energy: float = None, wavelength: float = None,
162
angle: float = None, q: float = None) -> float:
163
"""
164
Calculate X-ray reflectivity from a single-compound mirror.
165
166
Args:
167
compound: Mirror material
168
density: Material density in g/cm³
169
energy: X-ray energy in keV
170
wavelength: X-ray wavelength in Ångström
171
angle: Grazing angle in degrees
172
q: Momentum transfer in Ų⁻¹ (alternative to angle)
173
174
Returns:
175
Reflectivity (0-1)
176
"""
177
```
178
179
Usage examples:
180
181
```python
182
import periodictable as pt
183
from periodictable.xsf import index_of_refraction, mirror_reflectivity
184
import numpy as np
185
186
# Refractive index calculations
187
materials = ["Si", "SiO2", "Au", "Pt", "C"]
188
energy = 8.048 # keV, Cu K-alpha
189
190
print("Refractive indices at Cu K-alpha:")
191
for material in materials:
192
compound = pt.formula(material, density=pt.elements.symbol(material[0]).density)
193
n = index_of_refraction(compound, energy=energy)
194
delta = 1 - n.real
195
beta = -n.imag
196
print(f"{material:4s}: n = 1 - {delta:.6f} - i{beta:.6f}")
197
198
# Critical angle calculation (total external reflection)
199
silicon = pt.formula("Si", density=2.33)
200
n_si = index_of_refraction(silicon, energy=8.048)
201
critical_angle = np.sqrt(2 * (1 - n_si.real)) * 1000 # mrad
202
print(f"Si critical angle: {critical_angle:.2f} mrad")
203
204
# Mirror reflectivity vs angle
205
angles = np.logspace(-1, 1, 50) # 0.1 to 10 degrees
206
gold_mirror = pt.formula("Au", density=19.32)
207
208
reflectivities = []
209
for angle in angles:
210
R = mirror_reflectivity(gold_mirror, energy=8.048, angle=angle)
211
reflectivities.append(R)
212
213
# Find critical angle from reflectivity curve
214
critical_idx = np.where(np.array(reflectivities) < 0.5)[0]
215
if len(critical_idx) > 0:
216
print(f"Au mirror critical angle: ~{angles[critical_idx[0]]:.2f}°")
217
```
218
219
### Data Tables and Visualization
220
221
Generate formatted tables and plots of X-ray scattering data for analysis and reference.
222
223
```python { .api }
224
def sld_table(wavelength: float = None, energy: float = None,
225
table: PeriodicTable = None) -> None:
226
"""
227
Print X-ray SLD table for all elements.
228
229
Args:
230
wavelength: X-ray wavelength in Ångström
231
energy: X-ray energy in keV (alternative to wavelength)
232
table: Periodic table to use
233
"""
234
235
def emission_table(table: PeriodicTable = None) -> None:
236
"""Print X-ray emission line table for elements with data."""
237
238
def plot_xsf(element, energy_range: tuple = None, **kwargs) -> None:
239
"""
240
Plot X-ray scattering factors vs energy.
241
242
Args:
243
element: Element to plot
244
energy_range: (min_energy, max_energy) in keV
245
**kwargs: Additional plotting parameters
246
"""
247
```
248
249
Usage examples:
250
251
```python
252
import periodictable.xsf as xsf
253
import periodictable as pt
254
255
# Print SLD table at Cu K-alpha
256
xsf.sld_table(energy=8.048)
257
258
# Print emission line table
259
xsf.emission_table()
260
261
# Plot scattering factors (requires matplotlib)
262
try:
263
xsf.plot_xsf(pt.Si, energy_range=(5, 20))
264
xsf.plot_xsf(pt.Au, energy_range=(5, 50))
265
except ImportError:
266
print("Matplotlib required for plotting")
267
```
268
269
### Element X-ray Properties
270
271
Access detailed X-ray scattering properties for individual elements through the Xray class attached to atomic objects.
272
273
```python { .api }
274
class Xray:
275
"""X-ray scattering properties for elements."""
276
277
def scattering_factors(self, energy: float = None,
278
wavelength: float = None) -> tuple:
279
"""
280
Get f1, f2 scattering factors at given energy/wavelength.
281
282
Args:
283
energy: X-ray energy in keV
284
wavelength: X-ray wavelength in Ångström
285
286
Returns:
287
tuple: (f1, f2) scattering factors
288
"""
289
290
def f0(self, q: float) -> float:
291
"""
292
Atomic form factor f0 at momentum transfer q.
293
294
Args:
295
q: Momentum transfer in Ų⁻¹
296
297
Returns:
298
Atomic form factor f0
299
"""
300
301
def sld(self, density: float = None, energy: float = None,
302
wavelength: float = None) -> tuple:
303
"""
304
Calculate SLD for this element.
305
306
Args:
307
density: Mass density in g/cm³
308
energy: X-ray energy in keV
309
wavelength: X-ray wavelength in Ångström
310
311
Returns:
312
tuple: (sld_real, sld_imag)
313
"""
314
315
@property
316
def sftable(self) -> list:
317
"""Three-column table of energy vs f1, f2 scattering factors."""
318
```
319
320
Usage examples:
321
322
```python
323
import periodictable as pt
324
import numpy as np
325
326
# Element X-ray properties
327
silicon = pt.Si
328
329
if hasattr(silicon, 'xray') and silicon.xray:
330
# Scattering factors at Cu K-alpha
331
f1, f2 = silicon.xray.scattering_factors(energy=8.048)
332
print(f"Si scattering factors at Cu K-alpha: f1={f1:.3f}, f2={f2:.3f}")
333
334
# Atomic form factor at different q values
335
q_values = [0, 1, 2, 4, 8] # Ų⁻¹
336
print("Si atomic form factors:")
337
for q in q_values:
338
f0 = silicon.xray.f0(q)
339
print(f" q={q} Ų⁻¹: f0={f0:.3f}")
340
341
# SLD calculation
342
sld = silicon.xray.sld(density=2.33, energy=8.048)
343
print(f"Si SLD: {sld[0]:.4f} + {sld[1]:.4f}i")
344
345
# Access raw scattering factor table
346
table = silicon.xray.sftable
347
print(f"Scattering factor table has {len(table)} energy points")
348
349
# Compare different elements
350
elements = [pt.C, pt.Si, pt.Fe, pt.Au]
351
energy = 8.048 # keV
352
353
print(f"\nScattering factors at {energy} keV:")
354
for el in elements:
355
if hasattr(el, 'xray') and el.xray:
356
f1, f2 = el.xray.scattering_factors(energy=energy)
357
print(f"{el.symbol:2s}: f1={f1:6.3f}, f2={f2:6.3f}")
358
```
359
360
### Emission Line Data
361
362
Access X-ray emission line wavelengths for elements commonly used as X-ray sources.
363
364
```python { .api }
365
# Element properties (when available)
366
K_alpha: float # K-alpha emission line wavelength in Ångström
367
K_beta1: float # K-beta1 emission line wavelength in Ångström
368
K_alpha_units: str # Units for K-alpha (typically 'angstrom')
369
K_beta1_units: str # Units for K-beta1 (typically 'angstrom')
370
```
371
372
Usage examples:
373
374
```python
375
import periodictable as pt
376
377
# Common X-ray tube elements
378
tube_elements = [pt.Cr, pt.Fe, pt.Cu, pt.Mo, pt.Ag]
379
380
print("X-ray emission lines:")
381
for el in tube_elements:
382
if hasattr(el, 'K_alpha') and el.K_alpha:
383
energy_alpha = 12.398 / el.K_alpha # Convert Å to keV
384
print(f"{el.symbol} K-alpha: {el.K_alpha:.4f} Å ({energy_alpha:.3f} keV)")
385
386
if hasattr(el, 'K_beta1') and el.K_beta1:
387
energy_beta = 12.398 / el.K_beta1
388
print(f"{el.symbol} K-beta1: {el.K_beta1:.4f} Å ({energy_beta:.3f} keV)")
389
390
print()
391
392
# Copper detailed
393
copper = pt.Cu
394
if hasattr(copper, 'K_alpha'):
395
print(f"Cu K-alpha: {copper.K_alpha} {copper.K_alpha_units}")
396
print(f"Cu K-beta1: {copper.K_beta1} {copper.K_beta1_units}")
397
```
398
399
## Types
400
401
```python { .api }
402
class Xray:
403
"""X-ray scattering properties for elements."""
404
def scattering_factors(self, energy: float = None,
405
wavelength: float = None) -> tuple: ...
406
def f0(self, q: float) -> float: ...
407
def sld(self, density: float = None, energy: float = None,
408
wavelength: float = None) -> tuple: ...
409
@property
410
def sftable(self) -> list: ...
411
```