def GetMaterialMu(E, data): # send in the photon energy and the dictionary holding the layer information Ele = data['Element'] Mol = data['MolFrac'] t = 0 for i in range(len(Ele)): t += xraylib.AtomicWeight(xraylib.SymbolToAtomicNumber(Ele[i]))*Mol[i] mu=0 for i in range(len(Ele)): mu+= (xraylib.CS_Total(xraylib.SymbolToAtomicNumber(Ele[i]),E) * xraylib.AtomicWeight(xraylib.SymbolToAtomicNumber(Ele[i]))*Mol[i]/t) return mu # total attenuataion w/ coherent scattering in cm2/g
def test_attenuator(): # # create preprocessor file # symbol = "Cu" number_of_rays = 10000 cm_or_mm = 0 # 0=using cm, 1=using mm # # run prerefl # density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(symbol)) Shadow.ShadowPreprocessorsXraylib.prerefl(interactive=0, SYMBOL=symbol, DENSITY=density, FILE="prerefl.dat", E_MIN=5000.0, E_MAX=15000.0, E_STEP=100.0) # # run SHADOW for a sample of thickness 10 um # if cm_or_mm == 0: beam = run_example_attenuator(user_units_to_cm=1.0, npoint=number_of_rays) else: beam = run_example_attenuator(user_units_to_cm=0.1, npoint=number_of_rays) print("Intensity: %f" % (beam.intensity(nolost=1))) # # check SHADOW results against xraylib attenuation # cs1 = xraylib.CS_Total(xraylib.SymbolToAtomicNumber(symbol), 10.0) # print("xralib Fe cross section [cm^2/g]: %f"%cs1) # print("xralib mu [cm^-1]: %f"%(cs1*density)) sh100 = 100 * beam.intensity(nolost=1) / number_of_rays xrl100 = 100 * numpy.exp(-cs1 * density * 10e-4) print("xralib attenuation [per cent] for 10 um %s at 10 keV: %f" % (symbol, xrl100)) print("Transmission [per cent]: %f" % (sh100)) numpy.testing.assert_almost_equal(sh100, xrl100, 2)
def crlRadius(f, E, material='Be', density=None): if density is None: density = xraylib.ElementDensity( xraylib.SymbolToAtomicNumber(material)) #print getElementsName(material),E,density return f * 2. * (1. - xraylib.Refractive_Index_Re( getElementsName(material), E, density))
def getElementZ(inp): if type(inp) is int: return inp elif type(inp) is str: return xraylib.SymbolToAtomicNumber(inp) elif (not type(inp) is str) and np.iterable(inp): return [getElementZ(tinp) for tinp in inp]
def mendeljev_valid(value): try: atomic_number = xrl.SymbolToAtomicNumber(value) if atomic_number == 0: raise Exception() except Exception: raise ValidationError(f"Unknown chemical element {value}")
def get_delta(input_parameters, calculation_parameters): density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(input_parameters.crl_material)) energy_in_KeV = ShadowPhysics.getEnergyFromWavelength(calculation_parameters.gwavelength*input_parameters.widget.workspace_units_to_m*1e10)/1000 delta = 1-xraylib.Refractive_Index_Re(input_parameters.crl_material, energy_in_KeV, density) return delta
def get_element_atomic_number(element_str): r""" A wrapper to ``SymbolToAtomicNumber`` function from ``xraylib``. Returns atomic number for the sybmolic element name (e.g. ``C`` or ``Fe``). Parameters ---------- element_str: str sybmolic representation of an element Returns ------- Atomic number of the element ``element_str``. If element is invalid, then the function returns 0. """ if LooseVersion(xraylib.__version__) < LooseVersion("4.0.0"): xraylib.SetErrorMessages(0) # Turn off error messages from ``xraylib`` try: val = xraylib.SymbolToAtomicNumber(element_str) except ValueError: # Imitate the behavior of xraylib 3 val = 0 return val
def eleXRF_energy(ele, energy): Z = xl.SymbolToAtomicNumber(ele); F = xl.LineEnergy(Z, xl.KA1_LINE) if xl.EdgeEnergy(Z, xl.K_SHELL) > energy: F = xl.LineEnergy(Z, xl.LA1_LINE) elif xl.EdgeEnergy(Z, xl.L1_SHELL) > energy: F = xl.LineEnergy(Z, xl.LB1_LINE) elif xl.EdgeEnergy(Z, xl.L2_SHELL) > energy: F = xl.LineEnergy(Z, xl.LB1_LINE) elif xl.EdgeEnergy(Z, xl.L3_SHELL) > energy: F = xl.LineEnergy(Z, xl.LG1_LINE) elif xl.EdgeEnergy(Z, xl.M1_SHELL) > energy: F = xl.LineEnergy(Z, xl.MA1_LINE) return F
def GetDensity(material): if material == 'H2C': cpH2C = xrl.GetCompoundDataNISTByName('Polyethylene') density = cpH2C['density'] else: Z = xrl.SymbolToAtomicNumber(material) density = xrl.ElementDensity(Z) return density
def ug_to_mol(samp, map_key, scan_idx, eles, e_idx): e_list_idx = e_idx - 1 e = eles[e_list_idx] if len(e) > 2: e = e[:-2] else: pass z = xl.SymbolToAtomicNumber(e) factor = (1 / 1E6) * (1 / xl.AtomicWeight(z)) #(1g/1E6ug) * (1mol/g) mol_map = samp[map_key][scan_idx][e_idx, :, :-2] * factor return mol_map
def xoppy_calc_xf0(self): MAT_FLAG = self.MAT_FLAG DESCRIPTOR = self.DESCRIPTOR GRIDSTART = self.GRIDSTART GRIDEND = self.GRIDEND GRIDN = self.GRIDN qscale = numpy.linspace(GRIDSTART, GRIDEND, GRIDN) f0 = numpy.zeros_like(qscale) if MAT_FLAG == 0: # element descriptor = DESCRIPTOR for i, iqscale in enumerate(qscale): f0[i] = xraylib.FF_Rayl( xraylib.SymbolToAtomicNumber(descriptor), iqscale) elif MAT_FLAG == 1: # formula tmp = parse_formula(DESCRIPTOR) zetas = tmp["Elements"] multiplicity = tmp["n"] for j, jz in enumerate(zetas): for i, iqscale in enumerate(qscale): f0[i] += multiplicity[j] * xraylib.FF_Rayl(jz, iqscale) elif MAT_FLAG == 2: raise Exception("Not implemented") if self.DUMP_TO_FILE: with open(self.FILE_NAME, "w") as file: try: file.write("#F %s\n" % self.FILE_NAME) file.write("\n#S 1 xoppy f0 results\n") file.write("#N 2\n") file.write( "#L q=sin(theta)/lambda [A^-1] f0 [electron units]\n" ) for j in range(qscale.size): # file.write("%19.12e "%energy[j]) file.write("%19.12e %19.12e\n" % (qscale[j], f0[j])) file.close() print("File written to disk: %s \n" % self.FILE_NAME) except: raise Exception( "f0: The data could not be dumped onto the specified file!\n" ) # # return # return { "application": "xoppy", "name": "f0", "data": numpy.vstack((qscale, f0)), "labels": ["q=sin(theta)/lambda [A^-1]", "f0 [electron units]"] }
def get_delta_beta(cls, shadow_rays, material): beta = numpy.zeros(len(shadow_rays)) delta = numpy.zeros(len(shadow_rays)) density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(material)) for i in range(0, len(shadow_rays)): energy_in_KeV = ShadowPhysics.getEnergyFromShadowK(shadow_rays[i, 10])/1000 delta[i] = (1-xraylib.Refractive_Index_Re(material, energy_in_KeV, density)) beta[i] = xraylib.Refractive_Index_Im(material, energy_in_KeV, density) return delta, beta
def parse_raw_fluoro(fn, edge, trans, acqTime): rv = [] with open(fn) as f: total_count = 0 background_count = 0 for i, l in enumerate(f): if i > 2: e, cts = l.strip().split() total_count += float(cts) background_count += min(float(cts), 2) # crude but works I guess... if float(e) > (float(edge) - 1250.0): break if (total_count - background_count) > 100: FilePrefix = os.path.splitext(os.path.basename(fn))[0] pure_path = PurePath(fn).parts VisitDir = pure_path[:6] RestOfFilename = os.path.join(*pure_path[6:]) RestOfDirs = os.path.dirname(RestOfFilename) OutputDir = os.path.join(*VisitDir, 'processed/pymca', RestOfDirs) elf = os.path.join(OutputDir, FilePrefix) + '.results.dat' els = [] # contains lines like # Cu-K 7929.020000 90.714300 with open(elf) as f: rv.append("Element\tCounts\t%age\tExpected Emission Energies") for i, l in enumerate(f): el, pk, conf = l.strip().split() symbol, edge = el.split('-') Z = xrl.SymbolToAtomicNumber(symbol) edgesEnergies = "<b>{:g}</b>,{:g}".format( xrl.LineEnergy(Z, LINE_MAPPER[edge]) * 1000.0, xrl.EdgeEnergy(Z, EDGE_MAPPER[edge]) * 1000.0) if float(pk) >= 100000: counts = int(float(pk)) else: counts = round(float(pk), 1) rv.append("{}\t{:g}\t{:g}\t{}".format( el, counts, round(100 * float(pk) / total_count, 1), edgesEnergies)) if i == 5: break else: rv.append("No fluorescence peaks detected, try a higher transmission") rv.append("\nCounts (total): {:g} (background): {:g}".format( total_count, background_count)) return rv
def absorptionEdge(element, edge=None): if type(element) is str: element = xl.SymbolToAtomicNumber(element) shells = ["K", "L1", "L2", "L3", "M1", "M2", "M3", "M4", "M5"] if edge is not None: shell_ind = shells.index(edge) return xl.EdgeEnergy(element, shell_ind) else: shell_inds = range(8) print("Absorption edges %s" % xl.AtomicNumberToSymbol(element)) for shell_ind in shell_inds: print(" " + shells[shell_ind].ljust(3) + " = %7.1f eV" % (xl.EdgeEnergy(element, shell_ind) * 1000))
def validate_str(*s): boo = [] for i in s: try: if xraylib.SymbolToAtomicNumber(i) != 0: boo.append(True) elif xraylib.CompoundParser(i): boo.append(True) else: boo.append(False) except: return False return all(boo)
def calc_output(function, *values): xrl_function = getattr(xraylib, function) lst = [] for value in values: if validate_int(value): lst.append(int(value)) elif validate_float(value): lst.append(float(value)) elif check_xraylib_key(value): value = get_key(value) value = getattr(xraylib, value) lst.append(value) elif validate_str(value): if xraylib.SymbolToAtomicNumber(value) != 0: lst.append(xraylib.SymbolToAtomicNumber(value)) else: lst.append(value) #needed for _CP/compound string input try: # All objects in lst are integers or floats # excl. compound char i.e. int_z, int_z_or_comp or comp if validate_float(lst[0]): output = xrl_function(*lst) if output == 0: # Needed to render 0 in template return '0' else: return output else: xrl_function = getattr(xraylib, function + '_CP') output = xrl_function(*lst) if output == 0: return '0' else: return output except: output = 'Please enter valid input.' return output
def calculate_efficiency(cls, wavelength, zone_plate_material, zone_plate_thickness): energy_in_KeV = ShadowPhysics.getEnergyFromWavelength(wavelength*10)/1000 density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(zone_plate_material)) delta = (1-xraylib.Refractive_Index_Re(zone_plate_material, energy_in_KeV, density)) beta = xraylib.Refractive_Index_Im(zone_plate_material, energy_in_KeV, density) phi = 2*numpy.pi*zone_plate_thickness*delta/wavelength rho = beta/delta efficiency = (1/(numpy.pi**2))*(1 + numpy.exp(-2*rho*phi) - (2*numpy.exp(-rho*phi)*numpy.cos(phi))) max_efficiency = (1/(numpy.pi**2))*(1 + numpy.exp(-2*rho*numpy.pi) + (2*numpy.exp(-rho*numpy.pi))) thickness_max_efficiency = numpy.round(wavelength/(2*delta), 2) return efficiency, max_efficiency, thickness_max_efficiency
def XRF_line(Element, Beam_Energy): Z = xl.SymbolToAtomicNumber(str(Element)) F = xl.LineEnergy(Z, xl.KA1_LINE) if xl.EdgeEnergy(Z, xl.K_SHELL) > Beam_Energy: F = xl.LineEnergy(Z, xl.LA1_LINE) if xl.EdgeEnergy(Z, xl.L1_SHELL) > Beam_Energy: F = xl.LineEnergy(Z, xl.LB1_LINE) if xl.EdgeEnergy(Z, xl.L2_SHELL) > Beam_Energy: F = xl.LineEnergy(Z, xl.LB1_LINE) if xl.EdgeEnergy(Z, xl.L3_SHELL) > Beam_Energy: F = xl.LineEnergy(Z, xl.LG1_LINE) if xl.EdgeEnergy(Z, xl.M1_SHELL) > Beam_Energy: F = xl.LineEnergy(Z, xl.MA1_LINE) return F
def absorptionEdge(element,edge=None): if type(element) is str: element = xl.SymbolToAtomicNumber(element) shells = ['K','L1','L2','L3','M1','M2','M3','M4','M5'] if edge is not None: shell_ind = shells.index(edge) return xl.EdgeEnergy(element,shell_ind) else: shell_inds = range(8) print('Absorption edges %s'%xl.AtomicNumberToSymbol(element)) for shell_ind in shell_inds: print(' '\ +shells[shell_ind].ljust(3)\ +' = %7.1f eV'%(xl.EdgeEnergy(element,shell_ind)*1000))
def GetFluorescenceEnergy(Element,Beam): # send in the element and the beam energy to get the Excited Fluorescence Energy #this will return the highest energy fluorescence photon capable of being excited by the beam Z = xraylib.SymbolToAtomicNumber(Element) F = xraylib.LineEnergy(Z,xraylib.KA1_LINE) if xraylib.EdgeEnergy(Z,xraylib.K_SHELL) > Beam: F = xraylib.LineEnergy(Z,xraylib.LA1_LINE) if xraylib.EdgeEnergy(Z,xraylib.L1_SHELL) > Beam: F = xraylib.LineEnergy(Z,xraylib.LB1_LINE) if xraylib.EdgeEnergy(Z,xraylib.L2_SHELL) > Beam: F = xraylib.LineEnergy(Z,xraylib.LB1_LINE) if xraylib.EdgeEnergy(Z,xraylib.L3_SHELL) > Beam: F = xraylib.LineEnergy(Z,xraylib.LG1_LINE) if xraylib.EdgeEnergy(Z,xraylib.M1_SHELL) > Beam: F = xraylib.LineEnergy(Z,xraylib.MA1_LINE) return F
def get_Ele_XRF_Energy(ele, energy): Z = xl.SymbolToAtomicNumber(ele) #will it abosrb? if so, it will fluoresce F = xl.LineEnergy(Z, xl.KA1_LINE) if xl.EdgeEnergy(Z, xl.K_SHELL) > energy: F = xl.LineEnergy(Z, xl.LA1_LINE) if xl.EdgeEnergy(Z, xl.L1_SHELL) > energy: F = xl.LineEnergy(Z, xl.LB1_LINE) if xl.EdgeEnergy(Z, xl.L2_SHELL) > energy: F = xl.LineEnergy(Z, xl.LB1_LINE) if xl.EdgeEnergy(Z, xl.L3_SHELL) > energy: F = xl.LineEnergy(Z, xl.LG1_LINE) if xl.EdgeEnergy(Z, xl.M1_SHELL) > energy: F = xl.LineEnergy(Z, xl.MA1_LINE) return F
def ug_to_mol(self, elements): # get the XRF maps from each scan XRF_maps = [scan[-1:,:,:-2] for scan in self.maps] # get atomic number for xraylib reference z_list = [xl.SymbolToAtomicNumber(e) for e in elements] # calculate mol for each atomic number (1g/1E6ug)*(1mol/g) factors = [(1/1E6) * (1/xl.AtomicWeight(z)) for z in z_list] # convert factor list to array for easy matrix math factor_arr = np.array(factors) # 1D fact arr * 3D xrf arr along depth axis for each set of XRF maps XRF_mol = [factor_arr[:, None, None] * XRF_map for XRF_map in XRF_maps] # assign empty attribute to store mol maps self.mol = lambda:None # store mol maps; note these do not have electical map! self.mol = XRF_mol return
def edge(element=None, line='K', unit='eV'): ''' function return edge (K or L3) in eV or keV with input element sympbol ''' atomic_num = xraylib.SymbolToAtomicNumber(element) if line == 'K': edge_value = xraylib.EdgeEnergy(atomic_num, xraylib.K_SHELL) if line == 'L3': edge_value = xraylib.EdgeEnergy(atomic_num, xraylib.L3_SHELL) if unit == 'eV': return edge_value * 1000 else: return edge_value
def fluoro_emission_map(p, n_map, angle, el): """Compute the maia-detector-shaped map of K-edge fluorescence from the element map for an incident irradiance map n_map. Parameters ---------- p : Phantom2d object p.energy - incident beam photon energy (keV). p.um_per_px - length of one pixel of the map (um). n_map : 2d ndarray of float Map of incident irradiance. angle : float Stage rotation angle (degrees). el : string Name of fluorescing element (e.g. 'Fe'). Returns ------- 2d ndarray of float The fluorescence emission map for the requested edge. """ # edge_map = zero_outside_circle(p.el_maps[el]) edge_map = p.el_maps[el] edge_map_r = rotate(edge_map, angle) del edge_map # Get Z for the fluorescing element el_z = xrl.SymbolToAtomicNumber(el) line = xrl.KA_LINE # Sanity check that el K_alpha is below the incident energy. k_alpha_energy = xrl.LineEnergy(el_z, line) # assert k_alpha_energy < p.energy if k_alpha_energy >= p.energy: Q = 0.0 else: # Simulate fluorescence event: # CS_FluorLine_Kissel_Cascade is the XRF cross section Q_{i,YX} in Eq. (12) # of Schoonjans et al. Q = xrl.CS_FluorLine_Kissel_Cascade(el_z, line, p.energy) # print(el, end=' ') # 2d array for results emission_map = n_map * Q * edge_map_r * p.um_per_px / UM_PER_CM return emission_map
def test_lens(): # # inputs # cm_or_mm = 1 # 0=using cm, 1=using mm use_prerefl = 0 # 0=No, 1=Yes if cm_or_mm == 0: user_units_to_cm = 1.0 title = "Units are cm" elif cm_or_mm == 1: user_units_to_cm = 0.1 title = "Units are mm" else: print("No way...") # # run prerefl # if use_prerefl: import xraylib symbol = "Si" density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(symbol)) Shadow.ShadowPreprocessorsXraylib.prerefl(interactive=0, SYMBOL=symbol, DENSITY=density, FILE="prerefl.dat", E_MIN=5000.0, E_MAX=15000.0, E_STEP=100.0) # # run SHADOW # beam = run_example_lens(user_units_to_cm=user_units_to_cm) tkt = Shadow.ShadowTools.plotxy(beam, 3, 6, ref=0, nolost=1, nbins=301, title="Z,Z' " + title) print("Intensity: %f " % tkt["intensity"]) print("Number of rays: %d, number of GOOD rays: %d " % (beam.nrays(nolost=0), beam.nrays(nolost=1)))
def get_roi_from_XRF_line(self, XRFline): """This function determines the region of interest that should be used to represent an XRF line""" # first thing to do is determine which element and line we are dealing with # split the string along the dash try: (element, line) = XRFline.split('-') #print('element: ' + element) #print('line: ' + line) atomic_number = xraylib.SymbolToAtomicNumber(element) if (atomic_number == 0): raise ValueError( element + ' could not be parsed by xraylib.SymbolToAtomicNumber') #print('atomic_number:' + str(atomic_number)) # I can probably also get the same result with 'vars' line_macro = xraylib.__dict__[line.upper() + '_LINE'] #print('line_macro:' + str(line_macro)) line_energy = xraylib.LineEnergy(atomic_number, line_macro) #print('line_energy: ' + str(line_energy)) if (line_energy == 0.0): raise ValueError('XRF line ' + XRFline + ' does not exist in the xraylib database') if (self.PixelType != 2): raise ValueError( 'get_roi_from_XRF_line requires that the object has PixelType 2' ) channel = int(self.NBins * (line_energy - self.Emin) / (self.Emax - self.Emin)) #print('channel:' + str(channel)) if (channel < 0 or channel >= self.NBins): raise ValueError('requested XRF line not covered by spectrum') return slice(max(0, channel - 10), min(self.NBins - 1, channel + 10)) except Exception as e: raise Exception(str(e))
def element(request, element_id): # user may be naughty by providing a non-existent element if xrl.SymbolToAtomicNumber(element_id) == 0: messages.error( request, 'I am sure you already know that there is no element called ' + element_id + ' . Use the periodic table and stop fooling around.') return redirect('xasdb1:index') # make a distinction between staff and non-staff: # 1. staff should be able to see all spectra, regardless of review_status, and should be able to change that review_status elif request.user.is_staff: return render( request, 'xasdb1/element.html', { 'element': element_id, 'files': XASFile.objects.filter( element=element_id).order_by('sample_name') }) # 2. non-staff should be able to see all APPROVED spectra, as well as those uploaded by the user that were either rejected or pending review elif request.user.is_authenticated: data_filter = Q(uploader=request.user) | ( ~Q(uploader=request.user) & Q(review_status=XASFile.APPROVED)) return render( request, 'xasdb1/element.html', { 'element': element_id, 'files': XASFile.objects.filter(element=element_id).filter( data_filter).order_by('sample_name') }) else: return render( request, 'xasdb1/element.html', { 'element': element_id, 'files': XASFile.objects.filter(element=element_id).filter( review_status=XASFile.APPROVED).order_by('sample_name') })
def generateEPoints(ePointsGen, elem, kmin, kmax, kstep, reversed=True): """ Generates a list of energy values from the given list input: Tuples in the format (start energy, end energy, energy resolution), example: [(9.645,9.665,0.005),(9.666,9.7,0.0006),(9.705,9.725,0.005)] if reversed is true the list will be transposed return : list of energy points """ E0 = xraylib.EdgeEnergy(xraylib.SymbolToAtomicNumber(elem), xraylib.L3_SHELL) + ktoe(kmin) * 0.001 # kstart=2 #print(E0) krangeE = E0 + 0.001 * ktoe(np.arange(0.4, kmax, kstep)) e_points = [] if isinstance(ePointsGen[0], tuple): for values in ePointsGen: #use np.arange to generate values and extend it to the e_points list e_points.extend(np.arange(values[0], values[1], values[2])) edgeStart = values[1] + 0.001 e_points.extend(np.arange(edgeStart, E0, 0.001)) e_points.extend(krangeE) elif isinstance(ePointsGen, list): e_points = ePointsGen else: print(" Unknown energy list format") if reversed: #retrun list in the reversted order return np.around(e_points[::-1], 5) else: return np.around(e_points, 5)
def make_mol_maps(samples, elements, dict_data, new_dict_data): elements = [element[0:2] for element in elements] mol_masses = [ xl.AtomicWeight(xl.SymbolToAtomicNumber(element)) for element in elements ] #ug/cm2 * (g/ug) * (mol/g) == mol/cm2 conv_factors = [(1 / 1E6) / (1 / mol_mass) for mol_mass in mol_masses] for sample in samples: mol_scans = [] for scan_raw_maps in sample[dict_data]: mol_maps = scan_raw_maps.copy() for ele_idx, factor in enumerate(conv_factors): map_idx = ele_idx + 1 ele_map = scan_raw_maps[map_idx, :, :] mol_map = ele_map * factor mol_maps[map_idx, :, :] = mol_map mol_scans.append(mol_maps) samp_dict_grow.build_dict(sample, new_dict_data, mol_scans) return
def reflectivity(descriptor,energy,theta,density=None,rough=0.0): if isinstance(descriptor,str): Z = xraylib.SymbolToAtomicNumber(descriptor) symbol = descriptor else: Z = descriptor symbol = xraylib.AtomicNumberToSymbol(descriptor) if density == None: density = xraylib.ElementDensity(Z) atwt = xraylib.AtomicWeight(Z) avogadro = codata.Avogadro toangstroms = codata.h * codata.c / codata.e * 1e10 re = codata.e**2 / codata.m_e / codata.c**2 / (4*numpy.pi*codata.epsilon_0) * 1e2 # in cm molecules_per_cc = density * avogadro / atwt wavelength = toangstroms / energy * 1e-8 # in cm k = molecules_per_cc * re * wavelength * wavelength / 2.0 / numpy.pi f1 = numpy.zeros_like(energy) f2 = numpy.zeros_like(energy) for i,ienergy in enumerate(energy): f1[i] = Z + xraylib.Fi(Z,1e-3*ienergy) f2[i] = - xraylib.Fii(Z,1e-3*ienergy) alpha = 2.0 * k * f1 gamma = 2.0 * k * f2 rs,rp,runp = interface_reflectivity(alpha,gamma,theta) if rough != 0: rough *= 1e-8 # to cm debyewaller = numpy.exp( -( 4.0 * numpy.pi * numpy.sin(theta) * rough / wavelength)**2) else: debyewaller = 1.0 return rs*debyewaller,rp*debyewaller,runp*debyewaller