Example #1
0
def test_mu_elam():
    en = np.linspace(13000, 17000, 51)

    mu_total = np.array([
        67.46, 160.62, 158.03, 155.50, 153.03, 150.61, 148.24, 145.92, 143.66,
        141.44, 139.27, 137.14, 135.06, 133.02, 131.03, 129.07, 127.16, 125.28,
        123.45, 121.65, 119.88, 118.15, 116.46, 114.80, 113.17, 111.57, 110.03,
        108.52, 147.60, 145.79, 144.01, 142.26, 140.54, 138.86, 137.21, 135.58,
        154.36, 152.41, 150.50, 148.63, 146.79, 144.97, 143.19, 141.45, 139.73,
        138.04, 136.37, 134.74, 133.13, 131.55, 130.00
    ])

    mu_photo = np.array([
        63.54, 156.73, 154.16, 151.66, 149.21, 146.81, 144.46, 142.17, 139.93,
        137.73, 135.58, 133.48, 131.42, 129.40, 127.43, 125.50, 123.61, 121.75,
        119.94, 118.16, 116.41, 114.71, 113.03, 111.39, 109.78, 108.21, 106.69,
        105.19, 144.30, 142.50, 140.74, 139.01, 137.31, 135.65, 134.01, 132.41,
        151.20, 149.27, 147.38, 145.52, 143.70, 141.90, 140.14, 138.41, 136.71,
        135.03, 133.39, 131.77, 130.18, 128.62, 127.08
    ])

    mu_coh = np.array([
        3.86, 3.84, 3.82, 3.79, 3.77, 3.74, 3.72, 3.70, 3.67, 3.65, 3.63, 3.60,
        3.58, 3.56, 3.54, 3.52, 3.49, 3.47, 3.45, 3.43, 3.41, 3.39, 3.37, 3.35,
        3.33, 3.31, 3.29, 3.27, 3.25, 3.23, 3.21, 3.19, 3.17, 3.15, 3.13, 3.12,
        3.10, 3.08, 3.06, 3.04, 3.03, 3.01, 2.99, 2.97, 2.96, 2.94, 2.92, 2.91,
        2.89, 2.87, 2.86
    ])

    mu_incoh = np.array([
        0.05432, 0.05453, 0.05474, 0.05495, 0.05515, 0.05536, 0.05556, 0.05576,
        0.05596, 0.05616, 0.05636, 0.05656, 0.05675, 0.05695, 0.05714, 0.05734,
        0.05753, 0.05772, 0.05791, 0.05810, 0.05828, 0.05847, 0.05865, 0.05884,
        0.05902, 0.05920, 0.05939, 0.05957, 0.05974, 0.05992, 0.06010, 0.06028,
        0.06045, 0.06063, 0.06080, 0.06097, 0.06114, 0.06132, 0.06149, 0.06166,
        0.06182, 0.06199, 0.06216, 0.06232, 0.06249, 0.06265, 0.06282, 0.06298,
        0.06314, 0.06330, 0.06346
    ])

    assert_allclose(mu_total, mu_elam('Pb', en), rtol=0.01)
    assert_allclose(mu_photo, mu_elam('Pb', en, kind='photo'), rtol=0.01)
    assert_allclose(mu_incoh, mu_elam('Pb', en, kind='incoh'), rtol=0.01)
    assert_allclose(mu_coh, mu_elam('Pb', en, kind='coh'), rtol=0.01)

    with pytest.raises(ValueError):
        mu_elam('Pb', en, kind='all')

    # Check that array in -> array out, and scalar in -> scalar out
    assert mu_elam('Pb', [1000]).shape == (1, )
    assert isinstance(mu_elam('Pb', 1000), float)
Example #2
0
def scatteringdata(elem, e1, e2, de, fname):
    en_array = energy_array(e1, e2, de)
    mu_total = xraydb.mu_elam(elem, en_array, kind='total')
    mu_photo = xraydb.mu_elam(elem, en_array, kind='photo')
    mu_incoh = xraydb.mu_elam(elem, en_array, kind='incoh')
    mu_coher = xraydb.mu_elam(elem, en_array, kind='coh')

    header = [
        ' X-ray Atomic Scattering Cross-Sections from xrayweb  %s ' %
        time.ctime(),
        ' Element : %s ' % elem, ' Column.1: Energy (eV)',
        ' Column.2: mu_total (cm^2/gr)',
        ' Column.3: mu_photo (cm^2/gr)  # Photo-electric',
        ' Column.4: mu_coher (cm^2/gr)  # Rayleigh',
        ' Column.5: mu_incoh (cm^2/gr)  # Compton'
    ]

    arr_names = [
        'energy       ', 'mu_total     ', 'mu_photo     ', 'mu_coher     ',
        'mu_incoh     '
    ]

    arrays = [en_array, mu_total, mu_photo, mu_coher, mu_incoh]

    atz = xraydb.atomic_number(elem)
    if atz < 93:
        header.extend([
            ' Column.6: f1 (electrons/atom) # real resonant',
            ' Column.7: f2 (electrons/atom) # imag resonant'
        ])

        arr_names.extend(['f1           ', 'f2           '])
        arrays.extend([
            xraydb.f1_chantler(elem, en_array),
            xraydb.f2_chantler(elem, en_array)
        ])

    txt = make_asciifile(header, arr_names, arrays)
    return Response(txt, mimetype='text/plain')
Example #3
0
#!/usr/bin/env python
# XrayDB example script python/examples/mu_components_Fe.py
#
# plot components of X-ray mass attenuation for Fe
#
import numpy as np
import matplotlib.pyplot as plt
from xraydb import mu_elam

energy = np.arange(500, 120000, 10)  # energy in eV

elem = 'Fe'
mu_total = mu_elam(elem, energy, kind='total')
mu_photo = mu_elam(elem, energy, kind='photo')
mu_incoh = mu_elam(elem, energy, kind='incoh')
mu_coher = mu_elam(elem, energy, kind='coh')

plt.title('X-ray mass attenuation for %s' % elem)
plt.plot(energy, mu_total, linewidth=2, label='Total')
plt.plot(energy, mu_photo, linewidth=2, label='Photo-electric')
plt.plot(energy, mu_incoh, linewidth=2, label='Incoherent')
plt.plot(energy, mu_coher, linewidth=2, label='Coherent')

plt.xlabel('Energy (eV)')
plt.ylabel(r'$\mu/\rho \rm\, (cm^2/gr)$')
plt.legend()
plt.yscale('log')
plt.show()
Example #4
0
    def __init__(self,
                 symbol,
                 xray_energy=None,
                 energy_min=1.5,
                 overlap_energy=None):
        self.symbol = symbol
        self.xray_energy = xray_energy
        self.mu = 1.0
        self.edges = ['K']
        self.fyields = {}
        if xray_energy is not None:
            self.mu = mu_elam(symbol, 1000 * xray_energy, kind='photo')

            self.edges = []
            for ename, xedge in xray_edges(self.symbol).items():
                if ename.lower() in ('k', 'l1', 'l2', 'l3', 'm5'):
                    edge_kev = 0.001 * xedge.energy
                    if (edge_kev < xray_energy and edge_kev > energy_min):
                        self.edges.append(ename)
                        self.fyields[ename] = xedge.fyield

        # currently, we consider only one edge per element
        if 'K' in self.edges:
            self.edges = ['K']
        if 'L3' in self.edges:
            tmp = []
            for ename in self.edges:
                if ename.lower().startswith('l'):
                    tmp.append(ename)
            self.edges = tmp

        # apply CK corrections to fluorescent yields
        if 'L3' in self.edges:
            nlines = 1.0
            ck13 = ck_probability(symbol, 'L1', 'L3')
            ck12 = ck_probability(symbol, 'L1', 'L2')
            ck23 = ck_probability(symbol, 'L2', 'L3')
            fy3 = self.fyields['L3']
            fy2 = self.fyields.get('L2', 0)
            fy1 = self.fyields.get('L1', 0)
            if 'L2' in self.edges:
                nlines = 2.0
                fy3 = fy3 + fy2 * ck23
                fy2 = fy2 * (1 - ck23)
                if 'L1' in self.edges:
                    nlines = 3.0
                    fy3 = fy3 + fy1 * (ck13 + ck12 * ck23)
                    fy2 = fy2 + fy1 * ck12
                    fy1 = fy1 * (1 - ck12 - ck13 - ck12 * ck23)
                    self.fyields['L1'] = fy1
                self.fyields['L2'] = fy2
            self.fyields['L3'] = fy3 / nlines
            self.fyields['L2'] = fy2 / nlines
            self.fyields['L1'] = fy1 / nlines

        # look up X-ray lines, keep track of very close lines
        # so that they can be consolidate
        # slightly confusing (and working with XrayLine energies in ev)
        self.lines = {}
        self.all_lines = {}
        energy0 = None
        for ename in self.edges:
            for key, xline in xray_lines(symbol, ename).items():
                self.all_lines[key] = xline
                if xline.intensity > 0.002:
                    self.lines[key] = xline
                    if energy0 is None:
                        energy0 = xline.energy

        if overlap_energy is None:
            if xray_energy is None: xray_energy = 10.0
            if energy0 is not None: xray_energy = energy0
            # note: at this point xray_energy is in keV
            overlap_energy = 5.0 * (2 + np.sqrt(5 + xray_energy))

        # collect lines from the same initial level that are close in energy
        nlines = len(self.lines)
        combos = [[] for k in range(nlines)]
        comboe = [-1 for k in range(nlines)]
        combol = [None for k in range(nlines)]
        for key, xline in self.lines.items():
            assigned = False
            for i, en in enumerate(comboe):
                if (abs(0.001 * xline.energy - en) < overlap_energy
                        and xline.initial_level == combol[i]):
                    combos[i].append(key)
                    assigned = True
                    break
            if not assigned:
                for k in range(nlines):
                    if comboe[k] < 0:
                        break
                combol[k] = xline.initial_level
                comboe[k] = xline.energy
                combos[k].append(key)

        # consolidate overlapping X-ray lines
        for comps in combos:
            if len(comps) > 0:
                key = comps[0]
                l0 = self.lines.pop(key)
                ilevel = l0.initial_level
                iweight = l0.intensity
                flevel = [l0.final_level]
                en = [l0.energy]
                wt = [l0.intensity]
                for other in comps[1:]:
                    lx = self.lines.pop(other)
                    if lx.intensity > iweight:
                        iweight = lx.intensity
                        ilevel = lx.initial_level
                    flevel.append(lx.final_level)
                    en.append(lx.energy)
                    wt.append(lx.intensity)
                wt = np.array(wt)
                en = np.array(en)
                flevel = ', '.join(flevel)
                if len(comps) > 1:
                    newkey = key.replace('1', '').replace('2',
                                                          '').replace('3', '')
                    newkey = newkey.replace('4',
                                            '').replace('5',
                                                        '').replace(',', '')
                    if newkey not in self.lines:
                        key = newkey
                self.lines[key] = XrayLine(energy=(en * wt).sum() / wt.sum(),
                                           intensity=wt.sum(),
                                           initial_level=ilevel,
                                           final_level=flevel)
Example #5
0
def scattering(elem=None, e1='1000', e2='50000', de='50'):
    f1f2_plot = mu_plot = {}
    if len(request.form) != 0:
        elem = request.form.get('elem', 'None')
        e1 = request.form.get('e1', e1)
        e2 = request.form.get('e2', e2)
        de = request.form.get('de', de)

    if elem not in (None, 'None', ''):
        atz = xraydb.atomic_number(elem)
        en_array = energy_array(e1, e2, de)
        mu_total = xraydb.mu_elam(elem, en_array, kind='total')
        mu_photo = xraydb.mu_elam(elem, en_array, kind='photo')
        mu_incoh = xraydb.mu_elam(elem, en_array, kind='incoh')
        mu_coher = xraydb.mu_elam(elem, en_array, kind='coh')
        yrange = [
            -0.25 + min(-1.8, np.log10(mu_photo.min() + 1.e-5),
                        np.log10(mu_incoh.min() + 1.e-5),
                        np.log10(mu_coher.min() + 1.e-5)),
            0.75 + np.log10(mu_total.max() + 1.e-5)
        ]

        mu_plot = make_plot(en_array,
                            mu_total,
                            'Mass Attenuation for %s' % elem,
                            elem,
                            ytitle='mu/rho (cm^2/gr)',
                            xtitle='Energy (eV)',
                            xlog_scale=False,
                            ylog_scale=True,
                            yrange=yrange,
                            yformat='.2f',
                            y1label='Total',
                            y2=mu_photo,
                            y2label='Photo-electric',
                            y3=mu_incoh,
                            y3label='Incoherent',
                            y4=mu_coher,
                            y4label='Coherent')
        if atz < 93:
            try:
                f1 = xraydb.f1_chantler(elem, en_array)
            except:
                f1 = xraydb.f1_chantler(elem, en_array, smoothing=1)

            f2 = xraydb.f2_chantler(elem, en_array)
            f1f2_plot = make_plot(en_array,
                                  f1,
                                  'Resonant Scattering factors for %s' % elem,
                                  elem,
                                  ytitle='f1, f2 (electrons/atom)',
                                  xtitle='Energy (eV)',
                                  xlog_scale=False,
                                  ylog_scale=False,
                                  y2=f2,
                                  y1label='f1',
                                  y2label='f2')
    return render_template('scattering.html',
                           elem=elem,
                           e1=e1,
                           e2=e2,
                           de=int(de),
                           f1f2_plot=f1f2_plot,
                           mu_plot=mu_plot,
                           materials_dict=materials_dict)
Example #6
0
#!/usr/bin/env python
# XrayDB example script python/examples/mu_elements.py
#
# plot X-ray mass attenuation for selected elements
#
import numpy as np
import matplotlib.pyplot as plt
import wxmplot.interactive as wi
from xraydb import mu_elam, atomic_symbol

energy = np.arange(500, 120000, 10)  # energy in eV

for elem in ('C', 'Cu', 'Au'):
    mu = mu_elam(elem, energy)
    plt.plot(energy, mu, label=elem, linewidth=2)

plt.title('X-ray mass attenuation')
plt.xlabel('Energy (eV)')
plt.ylabel(r'$\mu/\rho \rm\, (cm^2/gr)$')
plt.legend()
plt.yscale('log')
plt.xscale('log')
plt.show()