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)
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')
#!/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()
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)
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)
#!/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()