def iio_vs_depth(ele, thickness_increments, dt): # percent incoming beam transmitted to CdTe layer iio_Mo = np.exp(-xl.CS_Total_CP('Mo', beam_energy) * MO['LDensity'] * MO['Thick'] / beam_geometry) iio_ZnTe = np.exp(-ZNTE['capXsect'] * ZNTE['LDensity'] * ZNTE['Thick'] / beam_geometry) iio_in = iio_Mo * iio_ZnTe # percent outgoing Cd_L transmitted by external layers ele_line = eleXRF_energy(ele, beam_energy) mu_Mo_ele_line = xl.CS_Total_CP('Mo', ele_line) #1800 vs. 1872 (matlab) mu_ZnTe_Cd_ele_line = xl.CS_Total_CP('ZnTe', ele_line) #653 vs. 680 (matlab) c_1 = np.exp(-mu_Mo_ele_line * MO['LDensity'] * MO['Thick'] / detect_geometry ) # moly is a really good Cd_L and Te_L absorber, iio ~0.0287 c_2 = np.exp(-mu_ZnTe_Cd_ele_line * ZNTE['LDensity'] * ZNTE['Thick'] / detect_geometry) iio_out = iio_in * c_1 * c_2 #0.0151 vs. 0.0163 (matlab) # percent outgoing Cd_L transmitted by CdTe itself #mu_CdTe_ele = xl.CS_Total_CP('CdTe', ele_line) iio_ele_cdte = np.zeros(len(thickness_increments)) cap_cross_section_of_one_sublayer_in = -xl.CS_Total_CP( 'CdTe', beam_energy) * CDTE['LDensity'] * dt / beam_geometry cap_cross_section_of_one_sublayer_out_ele = -xl.CS_Total_CP( 'CdTe', ele_line) * CDTE['LDensity'] * dt / detect_geometry for index, step in enumerate(thickness_increments): beam_in = cap_cross_section_of_one_sublayer_in * step beam_out = cap_cross_section_of_one_sublayer_out_ele * step iio_ele_cdte[index] = iio_out * np.exp(beam_in + beam_out) #iio_ele = np.mean(iio_ele_cdte) #0.00117 vs. 0.0021 (matlab) return iio_ele_cdte
def get_avg_internal_attn(layer_info, layer, elements, beam_settings, cum_upstrm_attn): beam_energy = beam_settings['beam_energy'] beam_rad = np.sin(beam_settings['beam_theta'] * np.pi / 180) det_rad = np.sin(beam_settings['detect_theta'] * np.pi / 180) density = layer_info[0] thickness = layer_info[1] step_size = 1 * 10**-7 # 1nm steps XRF_lines = [eleXRF_energy(element, beam_energy) for element in elements] thickness_nm = int(thickness * 1E7) sublayers_array = np.linspace(0, thickness_nm, thickness_nm + 1) ele_avg_iios = [] for ele_idx, XRF_line in enumerate(XRF_lines): each_sublayer_iios = np.zeros(len(sublayers_array)) sigma_sublayer_in = -xl.CS_Total_CP( layer, beam_energy) * density * step_size / beam_rad sigma_sublayer_out = -xl.CS_Total_CP( layer, XRF_line) * density * step_size / det_rad for sub_idx, sublayer in enumerate(sublayers_array): iio_in = sigma_sublayer_in * sublayer iio_out = sigma_sublayer_out * sublayer each_sublayer_iios[sub_idx] = cum_upstrm_attn[ele_idx] * np.exp( iio_in + iio_out) ### new proposed correction ### depth_idx_iio_bound = each_sublayer_iios[0] * (1 / np.e) characteristic_depth = get_char_depth(each_sublayer_iios, depth_idx_iio_bound) ele_avg_iio = np.mean(each_sublayer_iios[:characteristic_depth]) #print(ele_avg_iio) ele_avg_iios.append(ele_avg_iio) ele_avg_iios = np.array(ele_avg_iios) return ele_avg_iios
def get_mu(self, compound, energy, density): ''' returns mu for a compound for a single, or list, of energies ''' if isinstance(energy, (list)): op = [] for e in energy: op.append((xl.CS_Total_CP(compound, e) * density) * 1e-2) return op else: return (xl.CS_Total_CP(compound, energy) * density) * 1e-2
def mass_attenuation(energy, compound): ''' Total X-ray absorption for a given compound in cm2g. Energy is given in KeV ''' # xraylib might complain about types: energy = numpy.double(energy) if numpy.size(energy) == 1: return xraylib.CS_Total_CP(compound, energy) else: return numpy.array([xraylib.CS_Total_CP(compound, e) for e in energy])
def mu(x): #коэффициент поглощения c = 3.0 h = 6.62 e = 12.4 / x A = [] for ae in e: A.append(xraylib.CS_Total_CP("H2O", ae)) return A
def get_material_weight_factor(cls, shadow_rays, material, thickness): mu = numpy.zeros(len(shadow_rays)) for i in range(0, len(mu)): mu[i] = xraylib.CS_Total_CP(material, ShadowPhysics.getEnergyFromShadowK(shadow_rays[i, 10])/1000) # energy in KeV rho = ZonePlate.get_material_density(material) return numpy.sqrt(numpy.exp(-mu*rho*thickness*1e-7)) # thickness in CM
def absorb(y, x): #поглощение r = 5.32873 l = 0.01 c = 3.0 h = 6.62 e = 12.4 / x A = [] for ae in e: A.append(exp(-xraylib.CS_Total_CP("H2O", ae) * r * l)) return y * A
def iio_vs_depth(ele, thickness_increments, dt): # percent incoming beam transmitted by external layers iio_Au = np.exp(- xl.CS_Total_CP('Au', beam_energy) * AU['LDensity'] * AU['Thick'] / beam_geometry) iio_in = iio_Au # percent outgoing XRF line transmitted by external layers ele_line = eleXRF_energy(ele, beam_energy) mu_Mo_ele_line = xl.CS_Total_CP('Au', ele_line) #1800 vs. 1872 (matlab) c_1 = np.exp(- mu_Mo_ele_line * AU['LDensity'] * AU['Thick'] / detect_geometry) iio_out = iio_in * c_1 # percent outgoing XRF line transmitted by internal layer iio_ele_cdte = np.zeros(len(thickness_increments)) cap_cross_section_of_one_sublayer_in = - xl.CS_Total_CP('CdTe', beam_energy) * CDTE['LDensity'] * dt / beam_geometry cap_cross_section_of_one_sublayer_out_ele = - xl.CS_Total_CP('CdTe', ele_line) * CDTE['LDensity'] * dt / detect_geometry for index, step in enumerate(thickness_increments): beam_in = cap_cross_section_of_one_sublayer_in * step; beam_out = cap_cross_section_of_one_sublayer_out_ele * step iio_ele_cdte[index] = iio_out * np.exp(beam_in + beam_out) #iio_ele = np.mean(iio_ele_cdte) #0.00117 vs. 0.0021 (matlab) return iio_ele_cdte
def _selfabs_corr(self,z,line): if "name" not in [*self.tgt.keys()]: sys.stderr.write('Warning: _selfabs_corr, tgt has no name\n') return 0. name=self.tgt['name'] thickness=self.tgt['thickness'] density=self.tgt['density'] beamene=self.bem['beamene'] alpha=self.bem['beamalpha'] beta=self.bem['beambeta'] try: mu_0=xrl.CS_Total_CP(name, beamene) except: return 0. try: mu_1 = xrl.CS_Total_CP(name, line_wrap.get_lineenergy(z,line)) except: return 0. chi = mu_0/np.sin(np.pi/180.*alpha) + mu_1/np.sin(np.pi/180.*beta) A_corr = (1.0-np.exp(-chi*density*thickness))/(chi*density*thickness) return A_corr
def get_upstream_iioIN(layers_before, beam_settings): # convert to radians beam_rad = np.sin(beam_settings['beam_theta'] * np.pi / 180) iios = [] for layer, layer_info in layers_before.items(): # capture cross-section of upstream layer sigma = xl.CS_Total_CP(layer, beam_settings['beam_energy']) # layer density and thickness density = layer_info[0] thickness = layer_info[1] iio = np.exp(-sigma * density * thickness / beam_rad) # layer transmission iios.append(iio) upstream_iio = np.prod(iios) # cumulative transmission of upstream layers return upstream_iio
def _absall(self): phabs_all=np.ones_like(self.enes_keV,dtype=np.float64) phabs_each=[] if len(self.dets)==0: sys.stderr.write('Warning: _photoel, no detector set\n') return phabs_all,phabs_each if "name" not in [*self.det.keys()]: sys.stderr.write('Warning: _photoel, no detector name\n') return phabs_all,phabs_each for det in self.dets: name=det['name'] thickness=det['thickness'] density=det['density'] each=np.exp(-np.array([xrl.CS_Total_CP(name,E) for E in self.enes_keV])*density*thickness) phabs_each.append(1.-each) phabs_all=phabs_all*each phabs_all=1.-phabs_all return phabs_all,phabs_each
def GetRegisteredValue(spectrum, detector): """ Return registred signal :param spectrum: X-Ray spectra :param detector: X-Ray detector :return: registred signal intensity """ ab_eff = [] for e in spectrum.energy: cross_section = xraylib.CS_Total_CP(detector.scintillator_matter, e) ab_eff.append(1.0 - np.exp(-cross_section * detector.scintillator_density * detector.scintillator_thickness)) reg_val = np.sum(ab_eff * spectrum.intensity) / len(ab_eff) reg_val *= detector.efficiency return reg_val
def absorb2(E): #поглощение """ This function calculate the intensity of the radiation given absorption 0.5mm cuprum. :param l: wavelength :param intensity: intensity without absorption :param material: absorbing layer :param s: the thickness of the absorbing layer :returns: intensity with absorption :rtype: float """ r = 5.32873 c = 3.0 h = 6.62 e = E material = 'H2O' s = 0.01 res2 = func1(E) * exp(-xraylib.CS_Total_CP(material, E) * r * s) return res2
def absorb(intensity, E, material, s): #поглощение """ This function calculate the intensity of the radiation given absorption 0.5mm cuprum. :param l: wavelength :param intensity: intensity without absorption :param material: absorbing layer :param s: the thickness of the absorbing layer :returns: intensity with absorption :rtype: float """ r = 5.32873 c = 3.0 h = 6.62 e = E A = [] for ae in e: A.append(exp(-xraylib.CS_Total_CP(material, ae) * r * s)) return intensity * A
def _transmission(self): trans_all=np.ones_like(self.enes_keV,dtype=np.float64) trans_each=[] if len(self.bets)==0: sys.stderr.write('Warning: no filter materials data\n') return trans_all,trans_each if "name" not in [*self.bets[0].keys()]: sys.stderr.write('Warning: no filter materials data\n') return trans_all,trans_each for bet in self.bets: name=bet['name'] thickness=bet['thickness'] density=bet['density'] if (name=="LUXELHT"):# <- use LUXEL HT window each = self._trans_luxel_ht_window() else: each=np.exp(-np.array([xrl.CS_Total_CP(name,E) for E in self.enes_keV])*density*thickness) trans_each.append(each) trans_all=trans_all*each return trans_all,trans_each
def AddMatter(self, chemical_name, density, l, label=None): """ Add absorption matter :param chemical_name: Chemical formula of compund to be paresd in xraylib :param density: density [g/cm3] :param l: thickness [cm] :param label: matter label """ cross_section = [] for e in self.energy: cross_section.append(xraylib.CS_Total_CP(chemical_name, e)) mu = np.array(cross_section) * density absorp = np.exp(-mu * (l)) self.intensity = self.intensity * absorp if label is None: self.label = '{} + {} matter, {} cm'.format( self.label, chemical_name, l) else: self.label = '{} + {}'.format(self.label, label)
ele_rough_iios_up = np.stack(ele_rough_iios_up, axis=1) ele_rough_iios_down = [iio_vs_depth(ele, roughness, DT) for roughness in rough_downs] ele_rough_iios_down = np.stack(ele_rough_iios_down, axis=1) return ele_rough_iios_up, ele_rough_iios_down # SYCNHROTRON SETTINGS beam_energy = 12.7 #keV beam_theta = 90 #deg detect_theta = 47 #deg #deg to radians beam_geometry = np.sin(beam_theta*np.pi/180) detect_geometry = np.sin(detect_theta*np.pi/180) # layer dictionaries # all units in cm and g AU = {'Thick':100E-7, 'LDensity': 19.32, 'capXsect': xl.CS_Total_CP('Au', beam_energy)} CDTE = {'Thick':5.1E-4, 'LDensity': 5.85, 'capXsect': xl.CS_Total_CP('CdTe', beam_energy)} SE = {'Thick':100E-7, 'LDensity': 4.81, 'capXsect': xl.CS_Total_CP('Se', beam_energy)} # enter element ele = 'Se' # thickness increment; 1nm = 1E-7cm DT = 1*10**-7 # specify arbitrary depth of absorber (nm) DEPTH_STEPS = np.linspace(0, 12000, 12001) # calc incicent beam attenuation profile iio_beam = beamIn_vs_depth(DEPTH_STEPS, DT) # calc XRF reabsorption reference profile iio_ele = iio_vs_depth(ele, DEPTH_STEPS, DT)
def xoppy_calc_power3Dcomponent(self): # # important: the transmittivity calculated here is referred on axes perp to the beam # therefore they do not include geometrical corrections for correct integral # substance = self.EL1_FOR thick = self.EL1_THI angle = self.EL1_ANG defection = self.EL1_DEF dens = self.EL1_DEN roughness = self.EL1_ROU flags = self.EL1_FLAG hgap = self.EL1_HGAP vgap = self.EL1_VGAP hmag = self.EL1_HMAG vmag = self.EL1_VMAG hrot = self.EL1_HROT vrot = self.EL1_VROT if self.INPUT_BEAM_FROM == 1: self.load_input_file() p0, e0, h0, v0 = self.input_beam.get_content("xoppy_data") p = p0.copy() e = e0.copy() h = h0.copy() v = v0.copy() transmittance = numpy.ones_like(p) E = e.copy() H = h.copy() V = v.copy() # initialize results # # get undefined densities # if flags <= 1: try: # apply written value rho = float(dens) except: # in case of ? # grabber = TTYGrabber() # grabber.start() rho = density(substance) # grabber.stop() # for row in grabber.ttyData: # self.writeStdOut(row) print("Density for %s: %g g/cm3"%(substance,rho)) dens = rho txt = "" if flags == 0: txt += ' ***** oe [Filter] *************\n' txt += ' Material: %s\n'%(substance) txt += ' Density [g/cm^3]: %f \n'%(dens) txt += ' thickness [mm] : %f \n'%(thick) txt += ' H gap [mm]: %f \n'%(hgap) txt += ' V gap [mm]: %f \n'%(vgap) txt += ' H rotation angle [deg]: %f \n'%(hrot) txt += ' V rotation angle [deg]: %f \n'%(vrot) elif flags == 1: txt += ' ***** oe [Mirror] *************\n' txt += ' Material: %s\n'%(substance) txt += ' Density [g/cm^3]: %f \n'%(dens) txt += ' grazing angle [mrad]: %f \n'%(angle) txt += ' roughness [A]: %f \n'%(roughness) elif flags == 2: txt += ' ***** oe [Aperture] *************\n' txt += ' H gap [mm]: %f \n'%(hgap) txt += ' V gap [mm]: %f \n'%(vgap) elif flags == 3: txt += ' ***** oe [Magnifier] *************\n' txt += ' H magnification: %f \n'%(hmag) txt += ' V magnification: %f \n'%(vmag) elif flags == 4: txt += ' ***** oe [Screen rotated] *************\n' txt += ' H rotation angle [deg]: %f \n'%(hrot) txt += ' V rotation angle [deg]: %f \n'%(vrot) if flags == 0: # filter grabber = TTYGrabber() grabber.start() for j,energy in enumerate(e): tmp = xraylib.CS_Total_CP(substance,energy/1000.0) transmittance[j,:,:] = numpy.exp(-tmp*dens*(thick/10.0)) grabber.stop() for row in grabber.ttyData: self.writeStdOut(row) # rotation H = h / numpy.cos(hrot * numpy.pi / 180) V = v / numpy.cos(vrot * numpy.pi / 180) # aperture h_indices_bad = numpy.where(numpy.abs(H) > 0.5*hgap) if len(h_indices_bad) > 0: transmittance[:, h_indices_bad, :] = 0.0 v_indices_bad = numpy.where(numpy.abs(V) > 0.5*vgap) if len(v_indices_bad) > 0: transmittance[:, :, v_indices_bad] = 0.0 absorbance = 1.0 - transmittance elif flags == 1: # mirror tmp = numpy.zeros(e.size) for j,energy in enumerate(e): tmp[j] = xraylib.Refractive_Index_Re(substance,energy/1000.0,dens) if tmp[0] == 0.0: raise Exception("Probably the substrance %s is wrong"%substance) delta = 1.0 - tmp beta = numpy.zeros(e.size) for j,energy in enumerate(e): beta[j] = xraylib.Refractive_Index_Im(substance,energy/1000.0,dens) try: (rs,rp,runp) = reflectivity_fresnel(refraction_index_beta=beta,refraction_index_delta=delta,\ grazing_angle_mrad=angle,roughness_rms_A=roughness,\ photon_energy_ev=e) except: raise Exception("Failed to run reflectivity_fresnel") for j,energy in enumerate(e): transmittance[j,:,:] = rs[j] # rotation if defection == 0: # horizontally deflecting H = h / numpy.sin(self.EL1_ANG * 1e-3) elif defection == 1: # vertically deflecting V = v / numpy.sin(self.EL1_ANG * 1e-3) # size absorbance = 1.0 - transmittance h_indices_bad = numpy.where(numpy.abs(H) > 0.5*hgap) if len(h_indices_bad) > 0: transmittance[:, h_indices_bad, :] = 0.0 absorbance[:, h_indices_bad, :] = 0.0 v_indices_bad = numpy.where(numpy.abs(V) > 0.5*vgap) if len(v_indices_bad) > 0: transmittance[:, :, v_indices_bad] = 0.0 absorbance[:, :, v_indices_bad] = 0.0 elif flags == 2: # aperture h_indices_bad = numpy.where(numpy.abs(H) > 0.5*hgap) if len(h_indices_bad) > 0: transmittance[:, h_indices_bad, :] = 0.0 v_indices_bad = numpy.where(numpy.abs(V) > 0.5*vgap) if len(v_indices_bad) > 0: transmittance[:, :, v_indices_bad] = 0.0 absorbance = 1.0 - transmittance elif flags == 3: # magnifier H = h * hmag V = v * vmag absorbance = 1.0 - transmittance elif flags == 4: # rotation screen # transmittance[:, :, :] = numpy.cos(hrot * numpy.pi / 180) * numpy.cos(vrot * numpy.pi / 180) H = h / numpy.cos(hrot * numpy.pi / 180) V = v / numpy.cos(vrot * numpy.pi / 180) absorbance = 1.0 - transmittance txt += self.info_total_power(p, e, v, h, transmittance, absorbance) print(txt) calculated_data = (transmittance, absorbance, E, H, V) if self.FILE_DUMP == 0: pass elif self.FILE_DUMP == 1: self.xoppy_write_h5file(calculated_data) elif self.FILE_DUMP == 2: self.xoppy_write_txt(calculated_data, method="3columns") elif self.FILE_DUMP == 3: self.xoppy_write_txt(calculated_data, method="matrix") return calculated_data
beam_theta = 90 #angle of the beam relative to the surface of the sample beam_geometry = np.sin(beam_theta * np.pi / 180) #convert to radians detect_theta = 47 #angle of the detector relative to the beam detect_gemoetry = np.sin(detect_theta * np.pi / 180) #convert to radians dt = 10 * (1 * 10**-3) * ( 1 * 10**-4 ) #convert 10nm step sizes to cm: 10nm * (1um/1000nm) * (1cm/10000um) #enter lengths in cm SNO2 = { 'Element': ['Sn', 'O'], 'MolFrac': [1, 2], 'Thick': 0.00006, 'LDensity': 6.85, 'Name': 'SnO2', 'capXsect': xl.CS_Total_CP('SnO2', beam_energy) } CDS = { 'Element': ['Cd', 'S'], 'MolFrac': [1, 1], 'Thick': 0.000008, 'LDensity': 4.82, 'Name': 'CdS', 'capXsect': xl.CS_Total_CP('CdS', beam_energy) } CDTE = { 'Element': ['Cd', 'Te'], 'MolFrac': [1, 1], 'Thick': 0.0005, 'LDensity': 5.85, 'Name': 'CdTe',
def xoppy_calc_power3D(self): # # prepare input for xpower_calc # Note that the input for xpower_calc accepts any number of elements. # substance = [ self.EL1_FOR, self.EL2_FOR, self.EL3_FOR, self.EL4_FOR, self.EL5_FOR ] thick = numpy.array((self.EL1_THI, self.EL2_THI, self.EL3_THI, self.EL4_THI, self.EL5_THI)) angle = numpy.array((self.EL1_ANG, self.EL2_ANG, self.EL3_ANG, self.EL4_ANG, self.EL5_ANG)) dens = [ self.EL1_DEN, self.EL2_DEN, self.EL3_DEN, self.EL4_DEN, self.EL5_DEN ] roughness = numpy.array((self.EL1_ROU, self.EL2_ROU, self.EL3_ROU, self.EL4_ROU, self.EL5_ROU)) flags = numpy.array((self.EL1_FLAG, self.EL2_FLAG, self.EL3_FLAG, self.EL4_FLAG, self.EL5_FLAG)) substance = substance[0:self.NELEMENTS + 1] thick = thick[0:self.NELEMENTS + 1] angle = angle[0:self.NELEMENTS + 1] dens = dens[0:self.NELEMENTS + 1] roughness = roughness[0:self.NELEMENTS + 1] flags = flags[0:self.NELEMENTS + 1] p, e, h, v = self.input_beam.get_content("xoppy_data") nelem_including_source = self.NELEMENTS + 1 energies = e # initialize results # note that element of zero index corresponds to source!!! transmittance = numpy.zeros( (nelem_including_source, p.shape[0], p.shape[1], p.shape[2])) for i in range(nelem_including_source): transmittance[i] = numpy.ones_like(p) # # get undefined densities # for i in range(nelem_including_source): try: rho = float(dens[i]) except: rho = xraylib.ElementDensity( xraylib.SymbolToAtomicNumber(substance[i])) print("Density for %s: %g g/cm3" % (substance[i], rho)) dens[i] = rho #info oe txt = "" for i in range(self.NELEMENTS): if flags[i] == 0: txt += ' ***** oe ' + str( i + 1) + ' [Filter] *************\n' txt += ' Material: %s\n' % (substance[i]) txt += ' Density [g/cm^3]: %f \n' % (dens[i]) txt += ' thickness [mm] : %f \n' % (thick[i]) else: txt += ' ***** oe ' + str( i + 1) + ' [Mirror] *************\n' txt += ' Material: %s\n' % (substance[i]) txt += ' Density [g/cm^3]: %f \n' % (dens[i]) txt += ' grazing angle [mrad]: %f \n' % (angle[i]) txt += ' roughness [A]: %f \n' % (roughness[i]) for i in range(self.NELEMENTS): if flags[i] == 0: # filter for j, energy in enumerate(energies): tmp = xraylib.CS_Total_CP(substance[i], energy / 1000.0) # pay attention to the element index... transmittance[i + 1, j, :, :] = numpy.exp( -tmp * dens[i] * (thick[i] / 10.0)) if flags[i] == 1: # mirror tmp = numpy.zeros(energies.size) for j, energy in enumerate(energies): tmp[j] = xraylib.Refractive_Index_Re( substance[i], energy / 1000.0, dens[i]) delta = 1.0 - tmp beta = numpy.zeros(energies.size) for j, energy in enumerate(energies): beta[j] = xraylib.Refractive_Index_Im( substance[i], energy / 1000.0, dens[i]) (rs,rp,runp) = reflectivity_fresnel(refraction_index_beta=beta,refraction_index_delta=delta,\ grazing_angle_mrad=angle[i],roughness_rms_A=roughness[i],\ photon_energy_ev=energies) for j, energy in enumerate(energies): transmittance[i + 1, j, :, :] = rs[j] txt += "\n\n\n" integration_constante = (e[1] - e[0]) * (h[1] - h[0]) * ( v[1] - v[0]) * codata.e * 1e3 p_cumulated = p.copy() power_cumulated = p_cumulated.sum() * integration_constante txt += ' Input beam power: %f W\n' % (power_cumulated) for i in range(self.NELEMENTS): p_cumulated *= transmittance[i + 1] power_transmitted = (p_cumulated).sum() * integration_constante txt += ' Beam power after optical element %d: %6.3f W (absorbed: %6.3f W)\n'%\ (i+1,power_transmitted,power_cumulated-power_transmitted) power_cumulated = power_transmitted print(txt) return transmittance
def xoppy_calc_xraylib_widget(FUNCTION=0,ELEMENT=26,ELEMENTORCOMPOUND="FeSO4",COMPOUND="Ca5(PO4)3",TRANSITION_IUPAC_OR_SIEGBAHN=1,\ TRANSITION_IUPAC_TO=0,TRANSITION_IUPAC_FROM=0,TRANSITION_SIEGBAHN=0,SHELL=0,ENERGY=10.0): functions = [ '0 Fluorescence line energy', '1 Absorption edge energy', '2 Atomic weight', '3 Elemental density', '4 Total absorption cross section', '5 Photoionization cross section', '6 Partial photoionization cross section', '7 Rayleigh scattering cross section', '8 Compton scattering cross section', '9 Klein-Nishina cross section', '10 Mass energy-absorption cross section', '11 Differential unpolarized Klein-Nishina cross section', '12 Differential unpolarized Thomson cross section', '13 Differential unpolarized Rayleigh cross section', '14 Differential unpolarized Compton cross section', '15 Differential polarized Klein-Nishina cross section', '16 Differential polarized Thomson cross section', '17 Differential polarized Rayleigh cross section', '18 Differential polarized Compton cross section', '19 Atomic form factor', '20 Incoherent scattering function', '21 Momentum transfer function', '22 Coster-Kronig transition probability', '23 Fluorescence yield', '24 Jump factor', '25 Radiative transition probability', '26 Energy after Compton scattering', '27 Anomalous scattering factor φ′', '28 Anomalous scattering factor φ″', '29 Electronic configuration', '30 X-ray fluorescence production cross section (with full cascade)', '31 X-ray fluorescence production cross section (with radiative cascade)', '32 X-ray fluorescence production cross section (with non-radiative cascade)', '33 X-ray fluorescence production cross section (without cascade)', '34 Atomic level width', '35 Auger yield', '36 Auger rate', '37 Refractive index', '38 Compton broadening profile', '39 Partial Compton broadening profile', '40 List of NIST catalog compounds', '41 Get composition of NIST catalog compound', '42 List of X-ray emitting radionuclides', '43 Get excitation profile of X-ray emitting radionuclide', '44 Compoundparser' ] print("\nInside xoppy_calc_xraylib with FUNCTION = %s. " % (functions[FUNCTION])) if FUNCTION == 0: if TRANSITION_IUPAC_OR_SIEGBAHN == 0: lines = [ 'K', 'L1', 'L2', 'L3', 'M1', 'M2', 'M3', 'M4', 'M5', 'N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7', 'O1', 'O2', 'O3', 'O4', 'O5', 'O6', 'O7', 'P1', 'P2', 'P3', 'P4', 'P5', 'Q1', 'Q2', 'Q3' ] line = lines[TRANSITION_IUPAC_TO] + lines[ TRANSITION_IUPAC_FROM] + "_LINE" command = "result = xraylib.LineEnergy(%d,xraylib.%s)" % (ELEMENT, line) print("executing command: ", command) line = getattr(xraylib, line) result = xraylib.LineEnergy(ELEMENT, line) print("result: %f keV" % (result)) if TRANSITION_IUPAC_OR_SIEGBAHN == 1: lines = [ 'KA1_LINE', 'KA2_LINE', 'KB1_LINE', 'KB2_LINE', 'KB3_LINE', 'KB4_LINE', 'KB5_LINE', 'LA1_LINE', 'LA2_LINE', 'LB1_LINE', 'LB2_LINE', 'LB3_LINE', 'LB4_LINE', 'LB5_LINE', 'LB6_LINE', 'LB7_LINE', 'LB9_LINE', 'LB10_LINE', 'LB15_LINE', 'LB17_LINE', 'LG1_LINE', 'LG2_LINE', 'LG3_LINE', 'LG4_LINE', 'LG5_LINE', 'LG6_LINE', 'LG8_LINE', 'LE_LINE', 'LL_LINE', 'LS_LINE', 'LT_LINE', 'LU_LINE', 'LV_LINE' ] line = lines[TRANSITION_SIEGBAHN] command = "result = xraylib.LineEnergy(%d,xraylib.%s)" % (ELEMENT, line) print("executing command: ", command) line = getattr(xraylib, line) result = xraylib.LineEnergy(ELEMENT, line) print("result: %f keV" % (result)) if TRANSITION_IUPAC_OR_SIEGBAHN == 2: lines = [ 'K', 'L1', 'L2', 'L3', 'M1', 'M2', 'M3', 'M4', 'M5', 'N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7', 'O1', 'O2', 'O3', 'O4', 'O5', 'O6', 'O7', 'P1', 'P2', 'P3', 'P4', 'P5', 'Q1', 'Q2', 'Q3' ] for i1, l1 in enumerate(lines): for i2, l2 in enumerate(lines): if i1 != i2: line = l1 + l2 + "_LINE" try: line = getattr(xraylib, line) result = xraylib.LineEnergy(ELEMENT, line) except: pass else: if result != 0.0: print("%s%s %f keV" % (l1, l2, result)) elif FUNCTION == 1: shells = [ 'All shells', 'K_SHELL', 'L1_SHELL', 'L2_SHELL', 'L3_SHELL', 'M1_SHELL', 'M2_SHELL', 'M3_SHELL', 'M4_SHELL', 'M5_SHELL', 'N1_SHELL', 'N2_SHELL', 'N3_SHELL', 'N4_SHELL', 'N5_SHELL', 'N6_SHELL', 'N7_SHELL', 'O1_SHELL', 'O2_SHELL', 'O3_SHELL', 'O4_SHELL', 'O5_SHELL', 'O6_SHELL', 'O7_SHELL', 'P1_SHELL', 'P2_SHELL', 'P3_SHELL', 'P4_SHELL', 'P5_SHELL', 'Q1_SHELL', 'Q2_SHELL', 'Q3_SHELL' ] if SHELL == 0: #"all" for i, myshell in enumerate(shells): if i >= 1: # command = "result = xraylib.EdgeEnergy(%d,xraylib.%s)"%(ELEMENT,myshell) # print("executing command: ",command) shell_index = getattr(xraylib, myshell) try: result = xraylib.EdgeEnergy(ELEMENT, shell_index) except: pass else: if result != 0.0: print("%s %f keV" % (myshell, result)) else: print("No result") else: shell_index = getattr(xraylib, shells[SHELL]) try: command = "result = xraylib.EdgeEnergy(%d,xraylib.%s)" % ( ELEMENT, shells[SHELL]) print("executing command: ", command) result = xraylib.EdgeEnergy(ELEMENT, shell_index) except: pass else: if result != 0.0: print("Z=%d %s : %f keV" % (ELEMENT, shells[SHELL], result)) else: print("No result") elif FUNCTION == 2: result = xraylib.AtomicWeight(ELEMENT) if result != 0.0: print("Atomic weight for Z=%d : %f g/mol" % (ELEMENT, result)) elif FUNCTION == 3: result = xraylib.ElementDensity(ELEMENT) if result != 0.0: print("Element density for Z=%d : %f g/cm3" % (ELEMENT, result)) else: print("No result") elif FUNCTION == 4: command = "result = xraylib.CS_Total_CP('%s',%f)" % (ELEMENTORCOMPOUND, ENERGY) print("executing command: ", command) result = xraylib.CS_Total_CP(ELEMENTORCOMPOUND, ENERGY) if result != 0.0: print("Total absorption cross section: %f g/cm3" % (result)) else: print("No result") elif FUNCTION == 5: command = "result = xraylib.CS_Photo_CP('%s',%f)" % (ELEMENTORCOMPOUND, ENERGY) print("executing command: ", command) result = xraylib.CS_Photo_CP(ELEMENTORCOMPOUND, ENERGY) if result != 0.0: print("Photoionization cross section: %f g/cm3" % (result)) else: print("No result") elif FUNCTION == 6: shells = [ 'All shells', 'K_SHELL', 'L1_SHELL', 'L2_SHELL', 'L3_SHELL', 'M1_SHELL', 'M2_SHELL', 'M3_SHELL', 'M4_SHELL', 'M5_SHELL', 'N1_SHELL', 'N2_SHELL', 'N3_SHELL', 'N4_SHELL', 'N5_SHELL', 'N6_SHELL', 'N7_SHELL', 'O1_SHELL', 'O2_SHELL', 'O3_SHELL', 'O4_SHELL', 'O5_SHELL', 'O6_SHELL', 'O7_SHELL', 'P1_SHELL', 'P2_SHELL', 'P3_SHELL', 'P4_SHELL', 'P5_SHELL', 'Q1_SHELL', 'Q2_SHELL', 'Q3_SHELL' ] if SHELL == 0: #"all" for index in range(1, len(shells)): shell_index = getattr(xraylib, shells[index]) try: command = "result = xraylib.xraylib.CS_Photo_Partial('%d',xraylib.%s,%f)" % ( ELEMENT, shells[index], ENERGY) print("executing command: ", command) result = xraylib.CS_Photo_Partial(ELEMENT, shell_index, ENERGY) except: pass else: if result != 0.0: print("Z=%d, %s at E=%f keV: %f cm2/g" % (ELEMENT, shells[index], ENERGY, result)) else: print("No result") else: shell_index = getattr(xraylib, shells[SHELL]) try: command = "result = xraylib.xraylib.CS_Photo_Partial('%d',xraylib.%s,%f)" % ( ELEMENT, shells[SHELL], ENERGY) print("executing command: ", command) result = xraylib.CS_Photo_Partial(ELEMENT, shell_index, ENERGY) except: pass else: if result != 0.0: print("Z=%d, %s at E=%f keV: %f cm2/g" % (ELEMENT, shells[SHELL], ENERGY, result)) else: print("No result") elif FUNCTION == 7: command = "result = xraylib.CS_Rayl_CP('%s',%f)" % (ELEMENTORCOMPOUND, ENERGY) print("executing command: ", command) result = xraylib.CS_Rayl_CP(ELEMENTORCOMPOUND, ENERGY) if result != 0.0: print("Rayleigh cross section: %f cm2/g" % (result)) else: print("No result") elif FUNCTION == 8: command = "result = xraylib.CS_Compt_CP('%s',%f)" % (ELEMENTORCOMPOUND, ENERGY) print("executing command: ", command) result = xraylib.CS_Compt_CP(ELEMENTORCOMPOUND, ENERGY) if result != 0.0: print("Compton cross section: %f cm2/g" % (result)) else: print("No result") elif FUNCTION == 9: command = "result = xraylib.CS_KN(%f)" % (ENERGY) print("executing command: ", command) result = xraylib.CS_KN(ENERGY) if result != 0.0: print("Klein Nishina cross section: %f cm2/g" % (result)) else: print("No result") elif FUNCTION == 10: command = "result = xraylib.CS_Energy_CP('%s',%f)" % ( ELEMENTORCOMPOUND, ENERGY) print("executing command: ", command) result = xraylib.CS_Energy_CP(ELEMENTORCOMPOUND, ENERGY) if result != 0.0: print("Mass-energy absorption cross section: %f cm2/g" % (result)) else: print("No result") else: print("\n#### NOT YET IMPLEMENTED ####")
def total_attenuation(energy, compound): ''' Total X-ray absorption for a given compound in cm2g. Energy is given in KeV ''' return xraylib.CS_Total_CP(compound, energy)
def phantom_assign_concentration(ph_or, data_type=np.float32): """Builds the phantom used in: - N. Viganò and V. A. Solé, “Physically corrected forward operators for induced emission tomography: a simulation study,” Meas. Sci. Technol., no. Advanced X-Ray Tomography, pp. 1–26, Nov. 2017. :param ph_or: DESCRIPTION :type ph_or: TYPE :param data_type: DESCRIPTION, defaults to np.float32 :type data_type: TYPE, optional :return: DESCRIPTION :rtype: TYPE """ # ph_air = ph_or < 0.1 ph_FeO = 0.5 < ph_or ph_CaO = np.logical_and(0.25 < ph_or, ph_or < 0.5) ph_CaC = np.logical_and(0.1 < ph_or, ph_or < 0.25) conv_mm_to_cm = 1e-1 conv_um_to_mm = 1e-3 voxel_size_um = 0.5 voxel_size_cm = voxel_size_um * conv_um_to_mm * conv_mm_to_cm # cm to micron print("Sample size: [%g %g] um" % (ph_or.shape[0] * voxel_size_um, ph_or.shape[1] * voxel_size_um)) import xraylib xraylib.XRayInit() cp_fo = xraylib.GetCompoundDataNISTByName("Ferric Oxide") cp_co = xraylib.GetCompoundDataNISTByName("Calcium Oxide") cp_cc = xraylib.GetCompoundDataNISTByName("Calcium Carbonate") ca_an = xraylib.SymbolToAtomicNumber("Ca") ca_kal = xraylib.LineEnergy(ca_an, xraylib.KA_LINE) in_energy_keV = 20 out_energy_keV = ca_kal ph_lin_att_in = ( ph_FeO * xraylib.CS_Total_CP("Ferric Oxide", in_energy_keV) * cp_fo["density"] + ph_CaC * xraylib.CS_Total_CP("Calcium Carbonate", in_energy_keV) * cp_cc["density"] + ph_CaO * xraylib.CS_Total_CP("Calcium Oxide", in_energy_keV) * cp_co["density"]) ph_lin_att_out = ( ph_FeO * xraylib.CS_Total_CP("Ferric Oxide", out_energy_keV) * cp_fo["density"] + ph_CaC * xraylib.CS_Total_CP("Calcium Carbonate", out_energy_keV) * cp_cc["density"] + ph_CaO * xraylib.CS_Total_CP("Calcium Oxide", out_energy_keV) * cp_co["density"]) vol_att_in = ph_lin_att_in * voxel_size_cm vol_att_out = ph_lin_att_out * voxel_size_cm ca_cs = xraylib.CS_FluorLine_Kissel( ca_an, xraylib.KA_LINE, in_energy_keV) # fluo production for cm2/g ph_CaC_mass_fract = cp_cc["massFractions"][np.where( np.array(cp_cc["Elements"]) == ca_an)[0][0]] ph_CaO_mass_fract = cp_co["massFractions"][np.where( np.array(cp_co["Elements"]) == ca_an)[0][0]] ph = ph_CaC * ph_CaC_mass_fract * cp_cc[ "density"] + ph_CaO * ph_CaO_mass_fract * cp_co["density"] ph = ph * ca_cs * voxel_size_cm return (ph, vol_att_in, vol_att_out)
def get_xray_categories(self, xray_beam, measurement, output, new_sample=None): """ :param energy: beam energy in keV :param thickness: sample thickness in cm :param step: step length in cm :return: """ if new_sample is not None: self.sample = sample thickness = self.sample.thickness step = output.step energy = xray_beam.energy print("-----------------------------------------------") print("Energy: %.2f keV" % energy) print("Thickness limit: %.2f um" % thickness) print("Thickness resolution: %.2f um" % (step)) # Abbe criterion applied wavelen = xray_beam.wavelength num_aperture = measurement.get_numerical_aperture(xray_beam) (eta_el, eta_inel) = scat_efficiencies(energy, self.sample.mw, self.sample.elements, self.sample.stoic) # frac1 is the fraction in forward scattered (detectable) photons that finally enter the aperture frac1 = inna_frac(wavelen, num_aperture) # frac2 is the fraction of forward scattered inelastic scattered or plural scattered photons that enter the # aperture and contribute to PCI background frac2 = num_aperture ** 2 / 2 # retrieve cross sections in cm2/g cs_inel = xraylib.CS_Compt_CP(self.sample.compound, energy) cs_el = xraylib.CS_Rayl_CP(self.sample.compound, energy) cs_pi = xraylib.CS_Photo_CP(self.sample.compound, energy) cs_tot = xraylib.CS_Total_CP(self.sample.compound, energy) # probability per thickness k_el = cs_el * self.sample.density * 1e-4 k_inel = cs_inel * self.sample.density * 1e-4 k_elin = cs_el * (1 - eta_el) * self.sample.density * 1e-4 k_inelin = cs_inel * (1 - eta_inel) * self.sample.density * 1e-4 k_out = (cs_el * eta_el * self.sample.density + cs_inel * eta_inel * self.sample.density) * 1e-4 k_pi = cs_pi * self.sample.density * 1e-4 k_tot = k_inel + k_el + k_pi # intensity fractions relative to primary beam t = output.t i_noscat = np.exp(-k_tot * t) i_1el = k_elin * t * i_noscat i_1elpc = frac1 * i_1el i_pc = i_noscat + i_1elpc i_elpl = np.exp(-(k_inelin + k_out + k_pi) * t) - i_noscat - i_1el i_elplpc = i_elpl * frac2 i_out = (k_out / (k_out + k_pi)) * (1 - np.exp(-(k_out + k_pi) * t)) i_pi = (k_pi / (k_out + k_pi)) * (1 - np.exp(-(k_out + k_pi) * t)) i_inel = np.exp(-(k_out + k_pi) * t) - np.exp(-(k_inelin + k_out + k_pi) * t) i_inelpc = i_inel * frac2 # res = result_holder(xray_beam, output, measurement, i_noscat=i_noscat, i_1el=i_1el, i_1elpc=None, i_pc=i_pc, # i_elpl=i_elpl, i_elplpc=i_elplpc, i_out=i_out, i_pi=i_pi, i_inel=i_inel, i_inelpc=i_inelpc, # i_df=i_1elpc) res = result_holder(xray_beam, output, measurement, i_noscat=i_noscat, i_1el=i_1el, i_elpl=i_elpl, i_out=i_out, i_pi=i_pi, i_inel=i_inel) self.results.append(res) return