Пример #1
0
def _getFisxMaterials(fitConfiguration):
    """
    Given a PyMca fir configuration, return the list of fisx materials to be
    used by the library for calculation purposes.
    """
    global xcom
    if xcom is None:
        xcom = getElementsInstance()

    # define all the needed materials
    inputMaterialDict = fitConfiguration.get("materials", {})
    inputMaterialList = list(inputMaterialDict.keys())
    nMaterials = len(inputMaterialList)
    fisxMaterials = []
    processedMaterialList = []

    while (len(processedMaterialList) != nMaterials):
        for i in range(nMaterials):
            materialName = inputMaterialList[i]
            if materialName in processedMaterialList:
                # already defined
                pass
            else:
                thickness = inputMaterialDict[materialName].get("Thickness", 1.0)
                density = inputMaterialDict[materialName].get("Density", 1.0)
                comment = inputMaterialDict[materialName].get("Comment", "")
                if not len(comment):
                    comment = ""
                compoundList = inputMaterialDict[materialName]["CompoundList"]
                fractionList = inputMaterialDict[materialName]["CompoundFraction"]
                if not hasattr(fractionList, "__getitem__"):
                    compoundList = [compoundList]
                    fractionList = [fractionList]
                composition = {}
                for n in range(len(compoundList)):
                    composition[compoundList[n]] = fractionList[n]
                # check the composition is expressed in terms of elements
                # and not in terms of other undefined materials
                totallyDefined = True
                for element in composition:
                    #check if it can be understood
                    if not len(xcom.getComposition(element)):
                        # compound not understood
                        # probably we have a material defined in terms of other material
                        totallyDefined = False
                if totallyDefined:
                  fisxMaterial = Material(materialName,
                                          density=density,
                                          thickness=thickness,
                                          comment=comment)
                  fisxMaterial.setComposition(composition)
                  fisxMaterials.append(fisxMaterial)
                  processedMaterialList.append(materialName)
    return fisxMaterials
Пример #2
0
def _getFisxMaterials(fitConfiguration):
    """
    Given a PyMca fir configuration, return the list of fisx materials to be
    used by the library for calculation purposes.
    """
    global xcom
    if xcom is None:
        xcom = getElementsInstance()

    # define all the needed materials
    inputMaterialDict = fitConfiguration.get("materials", {})
    inputMaterialList = list(inputMaterialDict.keys())
    nMaterials = len(inputMaterialList)
    fisxMaterials = []
    processedMaterialList = []

    while (len(processedMaterialList) != nMaterials):
        for i in range(nMaterials):
            materialName = inputMaterialList[i]
            if materialName in processedMaterialList:
                # already defined
                pass
            else:
                thickness = inputMaterialDict[materialName].get(
                    "Thickness", 1.0)
                density = inputMaterialDict[materialName].get("Density", 1.0)
                comment = inputMaterialDict[materialName].get("Comment", "")
                if type(comment) in [type([])]:
                    # the user may have put a comma in the comment leading to
                    # misinterpretation of the string as a list
                    if len(comment) == 0:
                        comment = ""
                    elif len(comment) == 1:
                        comment = comment[0]
                    else:
                        actualComment = comment[0]
                        for commentPiece in comment[1:]:
                            actualComment = actualComment + "," + commentPiece
                        comment = actualComment
                if not len(comment):
                    comment = ""
                compoundList = inputMaterialDict[materialName]["CompoundList"]
                fractionList = inputMaterialDict[materialName][
                    "CompoundFraction"]
                if not hasattr(fractionList, "__getitem__"):
                    compoundList = [compoundList]
                    fractionList = [fractionList]
                composition = {}
                for n in range(len(compoundList)):
                    composition[compoundList[n]] = fractionList[n]
                # check the composition is expressed in terms of elements
                # and not in terms of other undefined materials
                totallyDefined = True
                for element in composition:
                    #check if it can be understood
                    if element in processedMaterialList:
                        # already defined
                        continue
                    elif not len(xcom.getComposition(element)):
                        # compound not understood
                        # probably we have a material defined in terms of other material
                        totallyDefined = False
                if totallyDefined:
                    try:
                        fisxMaterial = Material(materialName,
                                                density=density,
                                                thickness=thickness,
                                                comment=comment)
                        fisxMaterial.setComposition(composition)
                        fisxMaterials.append(fisxMaterial)
                    except:
                        if len(materialName):
                            raise TypeError("Error defining material <%s>" % \
                                            materialName)
                    processedMaterialList.append(materialName)
    return fisxMaterials
Пример #3
0
    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))
Пример #4
0
def _getFisxMaterials(fitConfiguration):
    """
    Given a PyMca fir configuration, return the list of fisx materials to be
    used by the library for calculation purposes.
    """
    global xcom
    if xcom is None:
        xcom = getElementsInstance()

    # define all the needed materials
    inputMaterialDict = fitConfiguration.get("materials", {})
    inputMaterialList = list(inputMaterialDict.keys())
    nMaterials = len(inputMaterialList)
    fisxMaterials = []
    processedMaterialList = []
    nIter = 10000
    while (len(processedMaterialList) != nMaterials) and (nIter > 0):
        nIter -= 1
        for i in range(nMaterials):
            materialName = inputMaterialList[i]
            if materialName in processedMaterialList:
                # already defined
                pass
            else:
                thickness = inputMaterialDict[materialName].get(
                    "Thickness", 1.0)
                if thickness <= 0:
                    raise ValueError("Invalid thickness %f" % thickness)
                density = inputMaterialDict[materialName].get("Density", 1.0)
                if density == 0.0:
                    raise ValueError("Invalid density %f" % density)
                comment = inputMaterialDict[materialName].get("Comment", "")
                if type(comment) in [type([])]:
                    # the user may have put a comma in the comment leading to
                    # misinterpretation of the string as a list
                    if len(comment) == 0:
                        comment = ""
                    elif len(comment) == 1:
                        comment = comment[0]
                    else:
                        actualComment = comment[0]
                        for commentPiece in comment[1:]:
                            actualComment = actualComment + "," + commentPiece
                        comment = actualComment
                if not len(comment):
                    comment = ""
                compoundList = inputMaterialDict[materialName]["CompoundList"]
                fractionList = inputMaterialDict[materialName][
                    "CompoundFraction"]
                if not hasattr(fractionList, "__getitem__"):
                    compoundList = [compoundList]
                    fractionList = [fractionList]
                composition = {}
                for n in range(len(compoundList)):
                    if fractionList[n] > 0.0:
                        composition[compoundList[n]] = fractionList[n]
                    else:
                        _logger.info("ignoring %s, fraction = %s",
                                     compoundList[n], fractionList[n])
                # check the composition is expressed in terms of elements
                # and not in terms of other undefined materials
                totallyDefined = True
                for element in composition:
                    #check if it can be understood
                    if element in processedMaterialList:
                        # already defined
                        continue
                    elif not len(xcom.getComposition(element)):
                        # compound not understood
                        # probably we have a material defined in terms of other material
                        totallyDefined = False
                if totallyDefined:
                    try:
                        fisxMaterial = Material(materialName,
                                                density=density,
                                                thickness=thickness,
                                                comment=comment)
                        fisxMaterial.setComposition(composition)
                        fisxMaterials.append(fisxMaterial)
                    except:
                        if len(materialName):
                            raise TypeError("Error defining material <%s>" % \
                                            materialName)
                    processedMaterialList.append(materialName)
    if len(processedMaterialList) < nMaterials:
        txt = "Undefined materials. "
        for material in inputMaterialList:
            if material not in processedMaterialList:
                txt += "\nCannot define material <%s>\nComposition " % material
                compoundList = inputMaterialDict[material]["CompoundList"]
                fractionList = inputMaterialDict[material]["CompoundFraction"]
                for compound in compoundList:
                    if not len(xcom.getComposition(compound)):
                        if compound not in processedMaterialList:
                            if compound + " " in processedMaterialList:
                                txt += "contains <%s> (defined as <%s>), " % (
                                    compound, compound + " ")
                            else:
                                txt += "contains <%s> (undefined)," % compound
        _logger.info(txt)
        raise KeyError(txt)
    return fisxMaterials
Пример #5
0
    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))
Пример #6
0
def _getFisxMaterials(webConfiguration, elementsInstance=None):
    """
    Given a user configuration, return the list of fisx materials to be
    used by the library for calculation purposes.
    """
    if elementsInstance is None:
        elementsInstance = getElementsInstance()

    # define all the needed materials
    # Web to module translator to simplify updates
    Thickness = "thickness"
    Density = "density"
    CompoundList = "compounds"
    CompoundFraction = "mass"
    Comment = "comment"
    Name = "name"

    inputMaterialList = webConfiguration.get("materials", [])
    nMaterials = len(inputMaterialList)
    fisxMaterials = []
    processedMaterialList = []

    lastProcessedMaterial = None
    while (len(processedMaterialList) != nMaterials):
        for i in range(nMaterials):
            inputMaterialDict = inputMaterialList[i]
            materialName = inputMaterialDict[Name]
            if materialName in processedMaterialList:
                # already defined
                pass
            elif lastProcessedMaterial == materialName:
                # prevent endless loop
                if not totallyDefined:
                    raise ValueError("Material '%s' not totally defined")
            else:
                thickness = inputMaterialDict.get(Thickness, 1.0)
                density = inputMaterialDict.get(Density, 1.0)
                comment = inputMaterialDict.get(Comment, "")
                if not len(comment):
                    comment = ""
                compoundList = inputMaterialDict[CompoundList]
                fractionList = inputMaterialDict[CompoundFraction]
                if not hasattr(fractionList, "__getitem__"):
                    compoundList = [compoundList]
                    fractionList = [fractionList]
                composition = {}
                for n in range(len(compoundList)):
                    composition[compoundList[n]] = float(fractionList[n])
                # check the composition is expressed in terms of elements
                # and not in terms of other undefined materials
                totallyDefined = True
                for element in composition:
                    #check if it can be understood
                    if not len(elementsInstance.getComposition(element)):
                        # compound not understood
                        # probably we have a material defined in terms of other material
                        totallyDefined = False
                if totallyDefined:
                    try:
                        fisxMaterial = Material(materialName,
                                                density=float(density),
                                                thickness=float(thickness),
                                                comment=comment)
                        fisxMaterial.setComposition(composition)
                        fisxMaterials.append(fisxMaterial)
                    except:
                        text = "Error defining material %s" % \
                                        materialName
                        text += "\n" + "%s" % (sys.exc_info()[1])
                        raise TypeError(text)
                    processedMaterialList.append(materialName)
            lastProcessedMaterial = materialName
    return fisxMaterials
Пример #7
0
def _getFisxMaterials(fitConfiguration):
    """
    Given a PyMca fir configuration, return the list of fisx materials to be
    used by the library for calculation purposes.
    """
    global xcom
    if xcom is None:
        xcom = getElementsInstance()

    # define all the needed materials
    inputMaterialDict = fitConfiguration.get("materials", {})
    inputMaterialList = list(inputMaterialDict.keys())
    nMaterials = len(inputMaterialList)
    fisxMaterials = []
    processedMaterialList = []
    nIter = 10000
    while (len(processedMaterialList) != nMaterials) and (nIter > 0):
        nIter -= 1
        for i in range(nMaterials):
            materialName = inputMaterialList[i]
            if materialName in processedMaterialList:
                # already defined
                pass
            else:
                thickness = inputMaterialDict[materialName].get("Thickness", 1.0)
                density = inputMaterialDict[materialName].get("Density", 1.0)
                comment = inputMaterialDict[materialName].get("Comment", "")
                if type(comment) in [type([])]:
                    # the user may have put a comma in the comment leading to
                    # misinterpretation of the string as a list
                    if len(comment) == 0:
                        comment = ""
                    elif len(comment) == 1:
                        comment = comment[0]
                    else:
                        actualComment = comment[0]
                        for commentPiece in comment[1:]:
                            actualComment = actualComment + "," + commentPiece
                        comment = actualComment
                if not len(comment):
                    comment = ""
                compoundList = inputMaterialDict[materialName]["CompoundList"]
                fractionList = inputMaterialDict[materialName]["CompoundFraction"]
                if not hasattr(fractionList, "__getitem__"):
                    compoundList = [compoundList]
                    fractionList = [fractionList]
                composition = {}
                for n in range(len(compoundList)):
                    composition[compoundList[n]] = fractionList[n]
                # check the composition is expressed in terms of elements
                # and not in terms of other undefined materials
                totallyDefined = True
                for element in composition:
                    # check if it can be understood
                    if element in processedMaterialList:
                        # already defined
                        continue
                    elif not len(xcom.getComposition(element)):
                        # compound not understood
                        # probably we have a material defined in terms of other material
                        totallyDefined = False
                if totallyDefined:
                    try:
                        fisxMaterial = Material(materialName, density=density, thickness=thickness, comment=comment)
                        fisxMaterial.setComposition(composition)
                        fisxMaterials.append(fisxMaterial)
                    except:
                        if len(materialName):
                            raise TypeError("Error defining material <%s>" % materialName)
                    processedMaterialList.append(materialName)
    if len(processedMaterialList) < nMaterials:
        txt = "Undefined materials. "
        for material in inputMaterialList:
            if material not in processedMaterialList:
                txt += "\nCannot define material <%s>\nComposition " % material
                compoundList = inputMaterialDict[material]["CompoundList"]
                fractionList = inputMaterialDict[material]["CompoundFraction"]
                for compound in compoundList:
                    if not len(xcom.getComposition(compound)):
                        if compound not in processedMaterialList:
                            if compound + " " in processedMaterialList:
                                txt += "contains <%s> (defined as <%s>), " % (compound, compound + " ")
                            else:
                                txt += "contains <%s> (undefined)," % compound
        print(txt)
        raise KeyError(txt)
    return fisxMaterials