def material_mu(name, energy, density=None, kind='total', _larch=None): """ material_mu(name, energy, density=None, kind='total') return X-ray attenuation length (in 1/cm) for a material by name or formula arguments --------- name: chemical formul or name of material from materials list. energy: energy or array of energies in eV density: material density (gr/cm^3). If None, and material is a known material, that density will be used. kind: 'photo' or 'total' (default) for whether to return photo-absorption or total cross-section. returns ------- mu, absorption length in 1/cm notes ----- 1. material names are not case sensitive, chemical compounds are case sensitive. 2. mu_elam() is used for mu calculation. example ------- >>> print material_mu('H2O', 10000.0) 5.32986401658495 """ _materials = get_materials(_larch) formula = None mater = _materials.get(name.lower(), None) if mater is not None: formula, density = mater else: for key, val in _materials.items(): if name.lower() == val[0].lower(): # match formula formula, density = val break # default to using passed in name as a formula if formula is None: formula = name if density is None: raise Warning('material_mu(): must give density for unknown materials') mass_tot, mu = 0.0, 0.0 for elem, frac in chemparse(formula).items(): mass = frac * atomic_mass(elem, _larch=_larch) mu += mass * mu_elam(elem, energy, kind=kind, _larch=_larch) mass_tot += mass return density*mu/mass_tot
def material_mu(name, energy, density=None, kind='total', _larch=None): """ material_mu(name, energy, density=None, kind='total') return X-ray attenuation length (in 1/cm) for a material by name or formula arguments --------- name: chemical formul or name of material from materials list. energy: energy or array of energies in eV density: material density (gr/cm^3). If None, and material is a known material, that density will be used. kind: 'photo' or 'total' (default) for whether to return photo-absorption or total cross-section. returns ------- mu, absorption length in 1/cm notes ----- 1. material names are not case sensitive, chemical compounds are case sensitive. 2. mu_elam() is used for mu calculation. example ------- >>> print(material_mu('H2O', 10000.0)) 5.32986401658495 """ _materials = get_materials(_larch) formula = None mater = _materials.get(name.lower(), None) if mater is not None: formula, density = mater else: for key, val in _materials.items(): if name.lower() == val[0].lower(): # match formula formula, density = val break # default to using passed in name as a formula if formula is None: formula = name if density is None: raise Warning('material_mu(): must give density for unknown materials') mass_tot, mu = 0.0, 0.0 for elem, frac in chemparse(formula).items(): mass = frac * atomic_mass(elem, _larch=_larch) mu += mass * mu_elam(elem, energy, kind=kind, _larch=_larch) mass_tot += mass return density * mu / mass_tot
def xray_delta_beta(material, density, energy, photo_only=False, _larch=None): """ return anomalous components of the index of refraction for a material, using the tabulated scattering components from Chantler. arguments: ---------- material: chemical formula ('Fe2O3', 'CaMg(CO3)2', 'La1.9Sr0.1CuO4') density: material density in g/cm^3 energy: x-ray energy in eV photo_only: boolean for returning photo cross-section component only if False (default), the total cross-section is returned returns: --------- (delta, beta, atlen) where delta : real part of index of refraction beta : imag part of index of refraction atlen : attenuation length in cm These are the anomalous scattering components of the index of refraction: n = 1 - delta - i*beta = 1 - lambda**2 * r0/(2*pi) Sum_j (n_j * fj) Adapted for Larch from code by Yong Choi """ lamb_cm = 1.e-8 * PLANCK_HC / energy # lambda in cm elements = [] for symbol, number in chemparse(material).items(): elements.append((number, Scatterer(symbol, energy, _larch=_larch))) total_mass, delta, beta_photo, beta_total = 0, 0, 0, 0 for (number, scat) in elements: weight = density*number*AVOGADRO delta += weight * scat.f1 beta_photo += weight * scat.f2 beta_total += weight * scat.f2*(scat.mu_total/scat.mu_photo) total_mass += number * scat.mass scale = lamb_cm * lamb_cm * R_ELECTRON_CM / (2*pi * total_mass) delta = delta * scale beta = beta_total * scale if photo_only: beta = beta_photo * scale return delta, beta, lamb_cm/(4*pi*beta)
def material_mu_components(name, energy, density=None, kind='total', _larch=None): """material_mu_components: absorption coefficient (in 1/cm) for a compound arguments --------- name: material name or compound formula energy: energy or array of energies at which to calculate mu density: compound density in gr/cm^3 kind: cross-section to use ('total', 'photo') for mu_elam()) returns ------- dictionary of data for constructing mu per element, with elements 'mass' (total mass), 'density', and 'elements' (list of atomic symbols for elements in material). For each element, there will be an item (atomic symbol as key) with tuple of (stoichiometric fraction, atomic mass, mu) larch> material_mu_components('quartz', 10000) {'Si': (1, 28.0855, 33.879432430185062), 'elements': ['Si', 'O'], 'mass': 60.0843, 'O': (2.0, 15.9994, 5.9528248152970837), 'density': 2.65} """ _materials = get_materials(_larch) mater = _materials.get(name.lower(), None) if mater is None: formula = name if density is None: raise Warning( 'material_mu(): must give density for unknown materials') else: formula, density = mater out = {'mass': 0.0, 'density': density, 'elements': []} for atom, frac in chemparse(formula).items(): mass = atomic_mass(atom, _larch=_larch) mu = mu_elam(atom, energy, kind=kind, _larch=_larch) out['mass'] += frac * mass out[atom] = (frac, mass, mu) out['elements'].append(atom) return out
def material_mu_components(name, energy, density=None, kind='total', _larch=None): """material_mu_components: absorption coefficient (in 1/cm) for a compound arguments --------- name: material name or compound formula energy: energy or array of energies at which to calculate mu density: compound density in gr/cm^3 kind: cross-section to use ('total', 'photo') for mu_elam()) returns ------- dictionary of data for constructing mu per element, with elements 'mass' (total mass), 'density', and 'elements' (list of atomic symbols for elements in material). For each element, there will be an item (atomic symbol as key) with tuple of (stoichiometric fraction, atomic mass, mu) larch> material_mu_components('quartz', 10000) {'Si': (1, 28.0855, 33.879432430185062), 'elements': ['Si', 'O'], 'mass': 60.0843, 'O': (2.0, 15.9994, 5.9528248152970837), 'density': 2.65} """ _materials = get_materials(_larch) mater = _materials.get(name.lower(), None) if mater is None: formula = name if density is None: raise Warning('material_mu(): must give density for unknown materials') else: formula, density = mater out = {'mass': 0.0, 'density': density, 'elements':[]} for atom, frac in chemparse(formula).items(): mass = atomic_mass(atom, _larch=_larch) mu = mu_elam(atom, energy, kind=kind, _larch=_larch) out['mass'] += frac*mass out[atom] = (frac, mass, mu) out['elements'].append(atom) return out