from moseley import ElementXRF
import matplotlib.pyplot as pltTheoretical peak patterns
In order to unravel measured x-ray fluorescence (XRF) spectra it is essential to be able to compute the theoretical spectral emission patterns for individual elements. An XRF spectrum consists of a number of peaks whose positions/energies (expressed in kilo electron Volt) are specific for a given element. To a first approximation the intensities of the peaks are proportional the concentration of the element. However if we look with more scrutiny it turns out that the exact height proportions of the peaks varies with the thickness of the sample. Let’s skip the theoretical background and simply plot such an XRF spectrum. For now, simply import ElementXRF() and instantiate it for lead (Pb).
If you are interested in the physics behind this, you can find the gory details in a later section…
Plotting a theoretical X-ray fluorescence spectrum can be done with the .plot_spectrum() method.
# initialize plot
fig, axs = plt.subplots(ncols=4, figsize=[15, 4], sharex=True, sharey=False)
axs = axs.flatten()
# iterate over a list of different sample thicknesses
for h_mm, ax in zip([0.001, 0.01, 0.1, 0.5], axs):
Pb_xrf = ElementXRF('Pb', h_mm=h_mm)
Pb_xrf.plot_spectrum(facecolor='k', ax=ax, xlim=[1, 17], vlines_colors='r')
ax.set_title(f'Pb (h={h_mm}mm)')
ax.set_xlim(xmax=20)
We can see here that these spectra (blue with black markers) for lead consist of multiple Gaussian shaped peaks. Most of these peaks are the result of closely spaced emission lines (red color). Each emission line corresponds to a specific transition of an electron between different electron shells. Although these patterns for lead samples of different thicknesses look fairly similar, their precise proportions vary.
If you want to inspect emission lines in detail you can take a look the .lines_table attribute.
Pb_xrf.lines_table # 0.5 mm| name | label | energy | trans_prob | fluo_yield | jump_coeff | attenuation | intensity | |
|---|---|---|---|---|---|---|---|---|
| 0 | Lb4 | Pb_L1M2 | 12.3070 | 0.338604 | 0.112000 | 0.135060 | 0.462812 | 0.002371 |
| 1 | Lb3 | Pb_L1M3 | 12.7950 | 0.401364 | 0.112000 | 0.135060 | 0.487145 | 0.002958 |
| 2 | Lg2 | Pb_L1N2 | 15.0991 | 0.114773 | 0.112000 | 0.135060 | 0.378123 | 0.000656 |
| 3 | Lg3 | Pb_L1N3 | 15.2175 | 0.145259 | 0.112000 | 0.135060 | 0.310437 | 0.000682 |
| 4 | Ln | Pb_L2M1 | 11.3490 | 0.018116 | 0.373000 | 0.285714 | 0.412679 | 0.000797 |
| 5 | Lb1 | Pb_L2M4 | 12.6140 | 0.787801 | 0.373000 | 0.285714 | 0.478221 | 0.040150 |
| 6 | Lg1 | Pb_L2N4 | 14.7657 | 0.165149 | 0.373000 | 0.285714 | 0.364340 | 0.006412 |
| 7 | Lg6 | Pb_L2O4 | 15.1793 | 0.028934 | 0.373000 | 0.285714 | 0.381387 | 0.001176 |
| 8 | Ll | Pb_L3M1 | 9.1840 | 0.037951 | 0.360000 | 0.600958 | 0.292015 | 0.002398 |
| 9 | La2 | Pb_L3M4 | 10.4490 | 0.076339 | 0.360000 | 0.600958 | 0.363219 | 0.005999 |
| 10 | La1 | Pb_L3M5 | 10.5510 | 0.683544 | 0.360000 | 0.600958 | 0.368916 | 0.054556 |
| 11 | Lb6 | Pb_L3N1 | 12.1432 | 0.010655 | 0.360000 | 0.600958 | 0.454454 | 0.001048 |
| 12 | Lb2,15 | Pb_L3N4,5 | 12.6007 | 0.169784 | 0.360000 | 0.600958 | 0.477560 | 0.017542 |
| 13 | Lb5 | Pb_L3O4,5 | 13.0143 | 0.021727 | 0.360000 | 0.600958 | 0.497792 | 0.002340 |
| 14 | Mg | Pb_M3N5 | 2.6538 | 1.000000 | 0.005047 | 0.137090 | 0.027508 | 0.000019 |
| 15 | Mb | Pb_M4N6 | 2.4443 | 0.997068 | 0.031350 | 0.209486 | 0.074410 | 0.000487 |
| 16 | Ma | Pb_M5N6,7 | 2.3423 | 1.000000 | 0.030775 | 0.430848 | 0.068258 | 0.000905 |
FUNCTIONS
get_attenuation
get_attenuation (element, emission_energy_keV, excitation_energy_keV='rhodium_Ka', h_mm=0.1)
*Attenuation factors for emissions at emission_keVs for pure sample with thickness h_mm.
See Thomsen_2007 equation 11.
Returns: att_list (array of floats)*
plot_pattern
plot_pattern (ptrn_dict, ax=None, offset=0, color=None)
Plot a single element peak pattern.
find_peaks
find_peaks (x, y, min_prom=0.001)
*Find peaks in spectrum x, y with minimal prominence min_prom=
Returns: peaks_xy*
gaussian_convolve
gaussian_convolve (peak_energies, peak_intensities, x_keVs=None, std=0.01)
*Convolves line spectrum defined by peak_energies and peak_intensities
with a Gaussian peak shape.*
ElementXRF
ElementXRF (element, excitation_energy_keV='rhodium_Ka', h_mm=0.1, x_keVs=None, std=0.01, min_prom=0.001)
Computes fluorescence emission line energies and intensities for element.
10/xraydb.material_mu('Pb', 22100)np.float64(0.013224338571882998)
# https://xraypy.github.io/XrayDB/examples.html#mu-calculations-for-materials
mu_20kev = xraydb.material_mu('CaCO3', 20000, density=2.71)
print("CaCO3 1/e depth at 20keV = {:.3f} mm".format(10/mu_20kev))CaCO3 1/e depth at 20keV = 0.648 mm
xraydb.chemparse('(PbCO3)2Pb(OH)2'){'Pb': 3.0, 'C': 2.0, 'O': 8.0, 'H': 2.0}
lead_white = '(PbCO3)2Pb(OH)2'mu_lead_white = xraydb.material_mu(lead_white, 22100,density=5)
10 * 1/mu_lead_whitenp.float64(0.03733713607717201)
Pb_rho = xraydb.atomic_density('Pb')
Pb_rho11.34
mass_mu_emiss = xraydb.mu_elam('Pb', 22100)
mass_mu_emissnp.float64(66.6826707720918)
element = 'Pb'
density = 11.34
energy = 22100
emission_depth_um = 10000/(xraydb.mu_elam(element, energy) * density)
emission_depth_umnp.float64(13.224338571882996)
10000 / xraydb.material_mu('Pb', energy, density=density)np.float64(13.224338571882999)