def getElementsInstance(dataDir=None, bindingEnergies=None, xcomFile=None): if dataDir is None: dataDir = DataDir.FISX_DATA_DIR try: from PyMca5.PyMcaDataDir import PYMCA_DATA_DIR as pymcaDataDir from PyMca5 import getDataFile except: _logger.info("Using fisx shell constants and ratios") pymcaDataDir = None if bindingEnergies is None: if pymcaDataDir is None: bindingEnergies = os.path.join(dataDir, "BindingEnergies.dat") else: bindingEnergies = getDataFile("BindingEnergies.dat") if xcomFile is None: if pymcaDataDir is None: xcomFile = os.path.join(dataDir, "XCOM_CrossSections.dat") else: xcomFile = getDataFile("XCOM_CrossSections.dat") t0 = time.time() instance = FisxElements(dataDir, bindingEnergies, xcomFile) _logger.debug("Shell constants") # the files should be taken from PyMca to make sure the same data are used for key in ["K", "L", "M"]: fname = instance.getShellConstantsFile(key) if sys.version > '3.0': # we have to make sure we have got a string if hasattr(fname, "decode"): fname = fname.decode("latin-1") _logger.debug("Before %s", fname) if pymcaDataDir is not None: fname = getDataFile(key + "ShellConstants.dat") else: fname = os.path.join(os.path.dirname(fname), key + "ShellConstants.dat") instance.setShellConstantsFile(key, fname) _logger.debug("After %s", instance.getShellConstantsFile(key)) _logger.debug("Radiative transitions") for key in ["K", "L", "M"]: fname = instance.getShellRadiativeTransitionsFile(key) if sys.version > '3.0': # we have to make sure we have got a string ... if hasattr(fname, "decode"): fname = fname.decode("latin-1") _logger.debug("Before %s", fname) if pymcaDataDir is not None: fname = getDataFile(key + "ShellRates.dat") else: fname = os.path.join(os.path.dirname(fname), key + "ShellRates.dat") instance.setShellRadiativeTransitionsFile(key, fname) _logger.debug("After %s ", instance.getShellRadiativeTransitionsFile(key)) _logger.debug("Reading Elapsed = %s", time.time() - t0) return instance
def testDetectorResults(self): from fisx import Elements from fisx import Detector elementsInstance = Elements() elementsInstance.initializeAsPyMca() # Make a detector from a formula detectorName = "NaI" detectorDensity = 4.0 detectorThickness = 0.00350 detectorInstance = Detector(detectorName, detectorDensity, detectorThickness) # Check the composition is returned as string and not bytes under # Python 3 composition = detectorInstance.getComposition(elementsInstance) if sys.version_info >= (3, ): for key in composition: self.assertTrue(isinstance(key, str), "Expected string, received %s" % type(key)) # check the returned keys are correct self.assertTrue(len(list(composition.keys())) == 2, "Incorrect number of keys returned") for key in ["Na", "I"]: self.assertTrue(key in composition, "key %s not found" % key) thickness = detectorInstance.getThickness() self.assertTrue(abs( thickness - detectorThickness) < 1.0e-7, "Wrong detector thickness!") density = detectorInstance.getDensity() self.assertTrue(abs(density - detectorDensity) < 1.0e-7, "Wrong detector density!") # check the return of the getEscape method escape = detectorInstance.getEscape(100.0, elementsInstance) if sys.version_info >= (3, ): for key in escape: self.assertTrue(isinstance(key, str), "Expected string, received %s" % type(key))
def testDetectorResults(self): from fisx import Elements from fisx import Detector elementsInstance = Elements() elementsInstance.initializeAsPyMca() # Make a detector from a formula detectorName = "NaI" detectorDensity = 4.0 detectorThickness = 0.00350 detectorInstance = Detector(detectorName, detectorDensity, detectorThickness) # Check the composition is returned as string and not bytes under # Python 3 composition = detectorInstance.getComposition(elementsInstance) if sys.version_info >= (3, ): for key in composition: self.assertTrue(isinstance(key, str), "Expected string, received %s" % type(key)) # check the returned keys are correct self.assertTrue( len(list(composition.keys())) == 2, "Incorrect number of keys returned") for key in ["Na", "I"]: self.assertTrue(key in composition, "key %s not found" % key) thickness = detectorInstance.getThickness() self.assertTrue( abs(thickness - detectorThickness) < 1.0e-7, "Wrong detector thickness!") density = detectorInstance.getDensity() self.assertTrue( abs(density - detectorDensity) < 1.0e-7, "Wrong detector density!") # check the return of the getEscape method escape = detectorInstance.getEscape(100.0, elementsInstance) if sys.version_info >= (3, ): for key in escape: self.assertTrue(isinstance(key, str), "Expected string, received %s" % type(key))
def getElementsInstance(dataDir=None, bindingEnergies=None, xcomFile=None): if dataDir is None: dataDir = DataDir.DATA_DIR if bindingEnergies is None: bindingEnergies = os.path.join(dataDir, "BindingEnergies.dat") if xcomFile is None: xcomFile = os.path.join(dataDir, "XCOM_CrossSections.dat") if DEBUG: t0 = time.time() instance = FisxElements(dataDir, bindingEnergies, xcomFile) if DEBUG: print("Shell constants") for key in ["K", "L", "M"]: fname = instance.getShellConstantsFile(key) if sys.version > '3.0': # we have to make sure we have got a string if hasattr(fname, "decode"): fname = fname.decode("latin-1") if DEBUG: print("Before %s" % fname) fname = os.path.join(os.path.dirname(fname), key + "ShellConstants.dat") instance.setShellConstantsFile(key, fname) if DEBUG: print("After %s" % instance.getShellConstantsFile(key)) if DEBUG: print("Radiative transitions") for key in ["K", "L", "M"]: fname = instance.getShellRadiativeTransitionsFile(key) if sys.version > '3.0': # we have to make sure we have got a string ... if hasattr(fname, "decode"): fname = fname.decode("latin-1") if DEBUG: print("Before %s" % fname) fname = os.path.join(os.path.dirname(fname), key + "ShellRates.dat") instance.setShellRadiativeTransitionsFile(key, fname) if DEBUG: print("After %s " % instance.getShellRadiativeTransitionsFile(key)) if DEBUG: print("Reading Elapsed = ", time.time() - t0) return instance
def testXRFResults(self): from fisx import Elements from fisx import Material from fisx import Detector from fisx import XRF elementsInstance = Elements() elementsInstance.initializeAsPyMca() # After the slow initialization (to be made once), the rest is fairly fast. xrf = XRF() xrf.setBeam( 16.0) # set incident beam as a single photon energy of 16 keV xrf.setBeamFilters([["Al1", 2.72, 0.11, 1.0]]) # Incident beam filters # Steel composition of Schoonjans et al, 2012 used to generate table I steel = { "C": 0.0445, "N": 0.04, "Si": 0.5093, "P": 0.02, "S": 0.0175, "V": 0.05, "Cr": 18.37, "Mn": 1.619, "Fe": 64.314, # calculated by subtracting the sum of all other elements "Co": 0.109, "Ni": 12.35, "Cu": 0.175, "As": 0.010670, "Mo": 2.26, "W": 0.11, "Pb": 0.001 } SRM_1155 = Material("SRM_1155", 1.0, 1.0) SRM_1155.setComposition(steel) elementsInstance.addMaterial(SRM_1155) xrf.setSample([["SRM_1155", 1.0, 1.0]]) # Sample, density and thickness xrf.setGeometry(45., 45.) # Incident and fluorescent beam angles detector = Detector("Si1", 2.33, 0.035) # Detector Material, density, thickness detector.setActiveArea(0.50) # Area and distance in consistent units detector.setDistance(2.1) # expected cm2 and cm. xrf.setDetector(detector) Air = Material("Air", 0.0012048, 1.0) Air.setCompositionFromLists( ["C1", "N1", "O1", "Ar1", "Kr1"], [0.0012048, 0.75527, 0.23178, 0.012827, 3.2e-06]) elementsInstance.addMaterial(Air) xrf.setAttenuators([["Air", 0.0012048, 5.0, 1.0], ["Be1", 1.848, 0.002, 1.0]]) # Attenuators fluo = xrf.getMultilayerFluorescence(["Cr K", "Fe K", "Ni K"], elementsInstance, secondary=2, useMassFractions=1) print( "\nElement Peak Energy Rate Secondary Tertiary" ) for key in fluo: for layer in fluo[key]: peakList = list(fluo[key][layer].keys()) peakList.sort() for peak in peakList: # energy of the peak energy = fluo[key][layer][peak]["energy"] # expected measured rate rate = fluo[key][layer][peak]["rate"] # primary photons (no attenuation and no detector considered) primary = fluo[key][layer][peak]["primary"] # secondary photons (no attenuation and no detector considered) secondary = fluo[key][layer][peak]["secondary"] # tertiary photons (no attenuation and no detector considered) tertiary = fluo[key][layer][peak].get("tertiary", 0.0) # correction due to secondary excitation enhancement2 = (primary + secondary) / primary enhancement3 = (primary + secondary + tertiary) / primary print("%s %s %.4f %.3g %.5g %.5g" % \ (key, peak + (13 - len(peak)) * " ", energy, rate, enhancement2, enhancement3)) # compare against expected values from Schoonjans et al. testXMI = True if (key == "Cr K") and peak.startswith("KL3"): second = 1.626 third = 1.671 elif (key == "Cr K") and peak.startswith("KM3"): second = 1.646 third = 1.694 elif (key == "Fe K") and peak.startswith("KL3"): second = 1.063 third = 1.064 elif (key == "Fe K") and peak.startswith("KL3"): second = 1.065 third = 1.066 else: testXMI = False if testXMI: discrepancy = 100 * (abs(second - enhancement2) / second) self.assertTrue(discrepancy < 1.5, "%s %s secondary discrepancy = %.1f %%" % \ (key, peak, discrepancy)) discrepancy = 100 * (abs(third - enhancement3) / third) self.assertTrue(discrepancy < 1.5, "%s %s tertiary discrepancy = %.1f %%" % \ (key, peak, discrepancy))
for i, element_attrs in enumerate(ptable): _draw_box(ax, element_attrs, facecolor=colors[i]) ax.set_xlim(0, 19) ax.set_ylim(8, 0) ax.axis('off'); if figname is not None: fig.savefig(figname) # fisx instantiation is needed before continuing elementsInstance = Elements() elementsInstance.initializeAsPyMca() class XFluo: def __init__(self, element, tube_keV, weight_list='equal', std=0.01, min_prom=0.001): '''Create an annotated x-ray fluorescence spectrum object. Args: element (str): Chemical symbol e.g 'Fe' tube_keV (float or list of floats): X-ray tube energies in keV. For a poly chromatic X-ray tube multiple energies can be provided. weight_list (list of numbers): X-ray energy weights. Corresponding to energy_list std (number): Peak width used for plotting min_prom (number): Minimal peak prominance.
def testXRFResults(self): from fisx import Elements from fisx import Material from fisx import Detector from fisx import XRF elementsInstance = Elements() elementsInstance.initializeAsPyMca() # After the slow initialization (to be made once), the rest is fairly fast. xrf = XRF() xrf.setBeam(16.0) # set incident beam as a single photon energy of 16 keV xrf.setBeamFilters([["Al1", 2.72, 0.11, 1.0]]) # Incident beam filters # Steel composition of Schoonjans et al, 2012 used to generate table I steel = {"C": 0.0445, "N": 0.04, "Si": 0.5093, "P": 0.02, "S": 0.0175, "V": 0.05, "Cr":18.37, "Mn": 1.619, "Fe":64.314, # calculated by subtracting the sum of all other elements "Co": 0.109, "Ni":12.35, "Cu": 0.175, "As": 0.010670, "Mo": 2.26, "W": 0.11, "Pb": 0.001} SRM_1155 = Material("SRM_1155", 1.0, 1.0) SRM_1155.setComposition(steel) elementsInstance.addMaterial(SRM_1155) xrf.setSample([["SRM_1155", 1.0, 1.0]]) # Sample, density and thickness xrf.setGeometry(45., 45.) # Incident and fluorescent beam angles detector = Detector("Si1", 2.33, 0.035) # Detector Material, density, thickness detector.setActiveArea(0.50) # Area and distance in consistent units detector.setDistance(2.1) # expected cm2 and cm. xrf.setDetector(detector) Air = Material("Air", 0.0012048, 1.0) Air.setCompositionFromLists(["C1", "N1", "O1", "Ar1", "Kr1"], [0.0012048, 0.75527, 0.23178, 0.012827, 3.2e-06]) elementsInstance.addMaterial(Air) xrf.setAttenuators([["Air", 0.0012048, 5.0, 1.0], ["Be1", 1.848, 0.002, 1.0]]) # Attenuators fluo = xrf.getMultilayerFluorescence(["Cr K", "Fe K", "Ni K"], elementsInstance, secondary=2, useMassFractions=1) print("\nElement Peak Energy Rate Secondary Tertiary") for key in fluo: for layer in fluo[key]: peakList = list(fluo[key][layer].keys()) peakList.sort() for peak in peakList: # energy of the peak energy = fluo[key][layer][peak]["energy"] # expected measured rate rate = fluo[key][layer][peak]["rate"] # primary photons (no attenuation and no detector considered) primary = fluo[key][layer][peak]["primary"] # secondary photons (no attenuation and no detector considered) secondary = fluo[key][layer][peak]["secondary"] # tertiary photons (no attenuation and no detector considered) tertiary = fluo[key][layer][peak].get("tertiary", 0.0) # correction due to secondary excitation enhancement2 = (primary + secondary) / primary enhancement3 = (primary + secondary + tertiary) / primary print("%s %s %.4f %.3g %.5g %.5g" % \ (key, peak + (13 - len(peak)) * " ", energy, rate, enhancement2, enhancement3)) # compare against expected values from Schoonjans et al. testXMI = True if (key == "Cr K") and peak.startswith("KL3"): second = 1.626 third = 1.671 elif (key == "Cr K") and peak.startswith("KM3"): second = 1.646 third = 1.694 elif (key == "Fe K") and peak.startswith("KL3"): second = 1.063 third = 1.064 elif (key == "Fe K") and peak.startswith("KL3"): second = 1.065 third = 1.066 else: testXMI = False if testXMI: discrepancy = 100 * (abs(second-enhancement2)/second) self.assertTrue(discrepancy < 1.5, "%s %s secondary discrepancy = %.1f %%" % \ (key, peak, discrepancy)) discrepancy = 100 * (abs(third-enhancement3)/third) self.assertTrue(discrepancy < 1.5, "%s %s tertiary discrepancy = %.1f %%" % \ (key, peak, discrepancy))
def getElementsInstance(): elementsInstance = Elements() elementsInstance.initializeAsPyMca() return elementsInstance