def check_if_eline_is_activated(elemental_line, incident_energy): """ Checks if emission line is activated at given incident beam energy Parameters ---------- elemental_line : str emission line in the format K_K or Fe_K incident_energy : float incident energy in keV Returns ------- bool value, indicating if the emission line is activated """ # Check if the emission line has correct format if not re.search(r"^[A-Z][a-z]?_[KLM]([ab]\d?)?$", elemental_line): raise RuntimeError(f"Elemental line {elemental_line} is improperly formatted") # The validation of 'elemental_line' is strict enough to do the rest of the processing # without further checks. [element, line] = elemental_line.split('_') line = line.lower() if len(line) == 1: line += 'a1' elif len(line) == 1: line += "1" e = Element(element) if e.cs(incident_energy)[line] == 0: return False else: return True
def get_line(ax, name, incident_energy): """ Plot emission lines for a given element. Parameters ---------- name : str or int element name, or atomic number incident_energy : float xray incident energy for fluorescence emission """ e = XrfElement(name) lines = e.emission_line.all ratio = [val for val in e.cs(incident_energy).all if val[1] > 0] i_min = 1e-6 for item in ratio: for data in lines: if item[0] == data[0]: ax.plot([data[1], data[1]], [i_min, item[1]], 'g-', linewidth=2.0) ax.set_title('Emission lines for %s at %s eV' % (name, incident_energy)) ax.set_xlabel('Energy [KeV]') ax.set_ylabel('Intensity')
def get_eline_parameters(elemental_line, incident_energy): """ Returns emission line parameters Parameters ---------- elemental_line : str emission line in the format K_K, Fe_K, Ca_k, Ca_ka, Ca_kb2 etc. incident_energy : float incident energy in keV Returns ------- dict Computed parameters of the emission line. Keys: "energy" (central energy of the peak), "cs" (crossection), "ratio" (normalized crossection, e.g. cs(Ca_kb2)/ cs(Ca_ka1) """ # Check if the emission line has correct format # TODO: verify the correnct range for lines (a-z covers all the cases, but may be too broad) if not re.search(r"^[A-Z][a-z]?_[KLMklm]([a-z]\d?)?$", elemental_line): raise RuntimeError( f"Elemental line {elemental_line} is improperly formatted") # The validation of 'elemental_line' is strict enough to do the rest of the processing # without further checks. [element, line] = elemental_line.split("_") line = line.lower() if len(line) == 1: line += "a1" elif len(line) == 2: line += "1" # This is the name of line #1 (ka1, la1 etc.) line_1 = line[0] + "a1" try: e = Element(element) energy = e.emission_line[line] cs = e.cs(incident_energy)[line] cs_1 = e.cs(incident_energy)[line_1] ratio = cs / cs_1 if cs_1 else 0 except Exception: energy, cs, ratio = 0, 0, 0 return {"energy": energy, "cs": cs, "ratio": ratio}
def run_demo(): import matplotlib.pyplot as plt e = XrfElement('Cu') print('Cu ka1 = %s' % e.emission_line['ka1']) print('all Cu emission lines\n{}'.format(e.emission_line.all)) print('fluorescence cross section of Cu at 12 eV = %s' % e.cs(12).all) print('showing spectrum for Cu at 12 eV') fig, ax = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True) ax = ax.ravel() get_line(ax[0], 'Cu', 12) get_spectrum(ax[1], 'Cu', 12) get_line(ax[2], 'Gd', 12) get_spectrum(ax[3], 'Gd', 12) plt.show()
def get_spectrum(ax, name, incident_energy, emax=15): """ Plot fluorescence spectrum for a given element. Parameters ---------- name : str or int element name, or atomic number incident_energy : float xray incident energy for fluorescence emission emax : float max value on spectrum """ e = XrfElement(name) lines = e.emission_line.all ratio = [val for val in e.cs(incident_energy).all if val[1] > 0] x = np.arange(0, emax, 0.01) spec = np.zeros(len(x)) i_min = 1e-6 for item in ratio: for data in lines: if item[0] == data[0]: ax.plot([data[1], data[1]], [i_min, item[1]], 'g-', linewidth=2.0) std = 0.1 area = std * np.sqrt(2 * np.pi) for item in ratio: for data in lines: if item[0] == data[0]: spec += gaussian(x, area, data[1], std) * item[1] #plt.semilogy(x, spec) ax.set_title('Simulated spectrum for %s at %s eV' % (name, incident_energy)) ax.set_xlabel('Energy [KeV]') ax.set_ylabel('Intensity') ax.plot(x, spec)