<jupyter_start><jupyter_text>Materials introductionMaterials can be defined as pure elements<jupyter_code>from spectrocrunch.materials import element

element1 = element.Element("Ca")
print(element1)<jupyter_output>Ca<jupyter_text>as compounds<jupyter_code>from spectrocrunch.materials import compoundfromformula
from spectrocrunch.materials import compoundfromname
from spectrocrunch.materials import compoundfromlist
from spectrocrunch.materials import types

compound1 = compoundfromformula.CompoundFromFormula("PbSO4",density=6.29)
compound2 = compoundfromformula.CompoundFromFormula("CaSO4",density=2.32)
compound3 = compoundfromname.compoundfromname("linseed oil")
compound4 = compoundfromlist.CompoundFromList(["Ca","C","O"],
                                              [1,1,3],
                                              types.fraction.mole,
                                              2.71,
                                              name="calcite")
print(compound1,compound2,compound3,compound4)<jupyter_output>PbSO4 CaSO4 linseed oil calcite<jupyter_text>and as mixtures of compounds<jupyter_code>from spectrocrunch.materials import mixture

mixture1 = mixture.Mixture([compound1,compound2],[0.5,0.5],\
                           types.fraction.mass,name="My mixture")
print(mixture1)<jupyter_output>50.00 wt% PbSO4 + 50.00 wt% CaSO4<jupyter_text>These materials can be used in a particular geometry (currently only flat multi-layered samples)<jupyter_code>from spectrocrunch.materials import multilayer
from spectrocrunch.detectors import xrf as xrfdetectors
from spectrocrunch.geometries import xrf as xrfgeometries
from spectrocrunch.sources import xray as xraysources

source = xraysources.factory("synchrotron")
detector = xrfdetectors.factory("leia")
geometry = xrfgeometries.factory("sxm120",
                                 detectorposition=-15.,
                                 detector=detector,
                                 source=source)

sample = multilayer.Multilayer(material=[element1,compound1,mixture1],
                               thickness=[1e-4,1e-4,1e-4],
                               geometry = geometry)
print(sample)
print("")
print(geometry)<jupyter_output>Multilayer (ordered top-bottom):
 Layer 0. 1.0 um (Ca)
 Layer 1. 1.0 um (PbSO4)
 Layer 2. 1.0 um (50.00 wt% PbSO4 + 50.00 wt% CaSO4)

XraySource:
 intensity = 0.9999999999999998 (W/m^2)
 dop = 1.0
 dolp = 1.0
 polangle = 0.0 (deg)
 handedness = none
XRF detector:
 Active area = 0.8 cm ** 2
 Ionization energy = 3.6685605263157894 eV
 Material = Si (0.045 cm)
Beam filters: None
Detector filters:
 ultralene = 0.0004064 cm
 Be = 0.0025 cm
MCA:
 zero = 0.0 eV
 gain = 5.0 eV
 noise = 50.0 eV (FWHM)
 fano = 0.19
Geometry:
 In = 62 deg
 Out = 58 deg (reflection)
 Sample azimuth = 180 deg
 Detector azimuth = 0 deg
 Distance = 42.0 mm
 Solid angle = 4*pi*0.0035703461329200104 srad
 Detector position = -15.0 mm<jupyter_text>Cross sectionsThe main usage of the material classes is to calculate cross sections. Current back-ends are [xraylib](https://github.com/tschoonj/xraylib) (elemental database, neglecting environment) and [FDMNES](http://neel.cnrs.fr/spip.php?rubrique1007&lang=en) (calculation with environment).- Mass attenuation coefficient (absorption + scattering)- Total scattering cross section- Rayleigh cross section- Compton cross section- Mass absorption coefficient (total photoionization cross-section)<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

energy = np.linspace(2,60,100)
material = mixture1

mu = material.mass_att_coeff(energy)
plt.plot(energy,mu,label='Total')
mu = material.mass_abs_coeff(energy)
plt.plot(energy,mu,label='Absorption')
mu = material.rayleigh_cross_section(energy)
plt.plot(energy,mu,label='Coherent')
mu = material.compton_cross_section(energy)
plt.plot(energy,mu,label='Incoherent')

plt.title(str(material))
plt.xlabel('Energy (keV)')
plt.ylabel('Cross-section (cm$^2$/g)')
plt.legend(loc='best')
plt.gca().set_yscale('log', basey=10)

plt.tight_layout()
plt.show()<jupyter_output>/data/id21/inhouse/wout/dev/virtualenvs/lid21data/spectrocrunch/py37/lib/python3.7/site-packages/ipykernel_launcher.py:21: MatplotlibDeprecationWarning: The 'basey' parameter of __init__() has been renamed 'base' since Matplotlib 3.3; support for the old name will be dropped two minor releases later.<jupyter_text>Partial cross sections- Partial photoionization cross section of a shell (fraction of absorption cross section)- Fluorescence cross section of an emission line: product of - the partial photoionization cross section of the excited shell - the fluorescence yield of the excited shell (fraction of shell cross section) - the radiative rate of the emission line (fraction of fluorescence yield)<jupyter_code>material = mixture1
material.unmarkabsorber()
print("Partial cross-section: no selection")
print('\n'.join(list(material.markinfo())))

energy = np.linspace(3,5,100)
mu = material.mass_abs_coeff(energy)
plt.plot(energy,mu,label='Absorption')

material.unmarkabsorber()
material.markabsorber("Ca",shells=['K'])
print("\nPartial cross-section: selected Ca-K")
print('\n'.join(list(material.markinfo())))

mu = material.partial_mass_abs_coeff(energy)
plt.plot(energy,mu,label='Ca-K')

mu = material.fluorescence_cross_section(energy)
plt.plot(energy,mu,label='Fluo (Ca-K)')

material.unmarkabsorber()
material.markabsorber("Ca",shells=['K'],fluolines=['KA'])
print("\nPartial cross-section: selected Ca-Ka")
print('\n'.join(list(material.markinfo())))

mu = material.fluorescence_cross_section(energy)
plt.plot(energy,mu,label='Fluo (Ca-Ka)')

plt.title(str(material))
plt.xlabel('Energy (keV)')
plt.ylabel('Cross-section (cm$^2$/g)')
plt.legend(loc='best')
plt.gca().set_yscale('log', basey=10)

plt.tight_layout()
plt.show()

material.unmarkabsorber()<jupyter_output>Partial cross-section: no selection
My mixture
 PbSO4
  Scatterer: yes
  Pb (no ionized shells)
  S (no ionized shells)
  O (no ionized shells)
 CaSO4
  Scatterer: yes
  Ca (no ionized shells)
  S (no ionized shells)
  O (no ionized shells)

Partial cross-section: selected Ca-K
My mixture
 PbSO4
  Scatterer: yes
  Pb (no ionized shells)
  S (no ionized shells)
  O (no ionized shells)
 CaSO4
  Scatterer: yes
  Ca ionized shells:
   K fluorescence lines: all
  S (no ionized shells)
  O (no ionized shells)

Partial cross-section: selected Ca-Ka
My mixture
 PbSO4
  Scatterer: yes
  Pb (no ionized shells)
  S (no ionized shells)
  O (no ionized shells)
 CaSO4
  Scatterer: yes
  Ca ionized shells:
   K fluorescence lines: KA
  S (no ionized shells)
  O (no ionized shells)<jupyter_text>Differential cross sectionsThe following differential cross sections with respect to the solid angle are available:- Rayleigh scattering (anisotropic)- Compton scattering (anisotropic)- Fluorescence (isotropic)<jupyter_code>azimuth = np.linspace(0,360,100)
polar = np.linspace(0,180,50)
extent = [azimuth[0],azimuth[-1],polar[0],polar[-1]]
azimuth,polar = np.meshgrid(np.radians(azimuth),np.radians(polar))

energy = 5
material = mixture1
print(material)

def plotcs(cs):
    plt.imshow(cs,origin="lower",extent=extent)
    plt.axhline(y=90)
    for x in [90,180,270]:
        plt.axvline(x=x)
    plt.xlabel("Azimuth (deg)")
    plt.ylabel("Polar (deg)")
    plt.colorbar(label="cm$^2$/g/sr")

cs = material.diff_rayleigh_cross_section(energy,source=source)
plotcs(cs(azimuth,polar))
plt.title("Elastic")
plt.show()

cs = material.diff_compton_cross_section(energy,source=source)
plotcs(cs(azimuth,polar))
plt.title("Inelastic")
plt.show()

material.markabsorber(energybounds=[1,energy])
cs = material.diff_fluorescence_cross_section(energy,source=source)
cs = np.full_like(azimuth,sum(cs.values()))
plotcs(np.full_like(azimuth,cs))
plt.title("Fluorescence")
plt.show()<jupyter_output>50.00 wt% PbSO4 + 50.00 wt% CaSO4<jupyter_text>X-ray spectra------------X-ray spectra are calculated from the cross-sections (including self-absorption). Alternatively the [fisx](https://github.com/vasole/fisx) library can be used as a back-end (no scattering; including self-absorption and secondary fluorescence).<jupyter_code>fig,axs = plt.subplots(2,2,figsize=(10,10))

energy = [5,5.1]
weights = [2,1]

emin = 2
emax = 5.5
azimuth = 0
polar = np.pi/2

plt.sca(axs[0][0])
spectrum = element1.xrayspectrum(energy,weights=weights,emax=emax,emin=emin,\
                                 source=source,azimuth=azimuth,polar=polar)
spectrum.plot()

plt.sca(axs[0][1])
spectrum = compound1.xrayspectrum(energy,weights=weights,emax=emax,emin=emin,\
                                  source=source,azimuth=azimuth,polar=polar)
spectrum.plot()

plt.sca(axs[1][0])
spectrum = mixture1.xrayspectrum(energy,weights=weights,emax=emax,emin=emin,\
                                 source=source,azimuth=azimuth,polar=polar)
spectrum.plot()

plt.sca(axs[1][1])
spectrum = sample.xrayspectrum(energy,weights=weights,emax=emax,emin=emin)
spectrum.plot()

plt.tight_layout()
plt.show()<jupyter_output>/data/id21/inhouse/wout/dev/virtualenvs/lid21data/spectrocrunch/py37/lib/python3.7/site-packages/numpy/core/_asarray.py:136: UnitStrippedWarning: The unit of the quantity is stripped when downcasting to ndarray.
  return array(a, dtype, copy=False, order=order, subok=True)
{'fraction_non_alphanumeric': 0.12040421414749516, 'fraction_numerical': 0.0326811438400344, 'mean_word_length': 4.604216867469879, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '538839', 'license': 'MIT', 'n_tokens_mistral': 3472, 'n_tokens_neox': 3052, 'n_words': 688, 'path': 'doc/source/tutorials/materials.ipynb', 'repo_name': 'woutdenolf/spectrocrunch', 'size': '9302'}