예제 #1
0
파일: XrfTest.py 프로젝트: sjmvm/pymca
    def testStainlessSteelDataFit(self):
        from PyMca5.PyMcaIO import specfilewrapper as specfile
        from PyMca5.PyMcaPhysics.xrf import ClassMcaTheory
        from PyMca5.PyMcaPhysics.xrf import ConcentrationsTool
        from PyMca5.PyMcaIO import ConfigDict

        # read the data
        dataFile = os.path.join(self.dataDir, "Steel.spe")
        self.assertTrue(os.path.isfile(dataFile),
                        "File %s is not an actual file" % dataFile)
        sf = specfile.Specfile(dataFile)
        self.assertTrue(len(sf) == 1, "File %s cannot be read" % dataFile)
        self.assertTrue(sf[0].nbmca() == 1, "Spe file should contain MCA data")
        y = counts = sf[0].mca(1)
        x = channels = numpy.arange(y.size).astype(numpy.float)
        sf = None

        # read the fit configuration
        configFile = os.path.join(self.dataDir, "Steel.cfg")
        self.assertTrue(os.path.isfile(configFile),
                        "File %s is not an actual file" % configFile)
        configuration = ConfigDict.ConfigDict()
        configuration.read(configFile)
        # configure the fit
        # make sure no secondary excitations are used
        configuration["concentrations"]["usemultilayersecondary"] = 0
        mcaFit = ClassMcaTheory.ClassMcaTheory()
        configuration = mcaFit.configure(configuration)
        mcaFit.setData(x,
                       y,
                       xmin=configuration["fit"]["xmin"],
                       xmax=configuration["fit"]["xmax"])
        mcaFit.estimate()
        fitResult, result = mcaFit.startFit(digest=1)

        # concentrations
        # fit is already done, calculate the concentrations
        concentrationsConfiguration = configuration["concentrations"]
        cTool = ConcentrationsTool.ConcentrationsTool()
        cToolConfiguration = cTool.configure()
        cToolConfiguration.update(configuration['concentrations'])

        # make sure we are using Fe as internal standard
        matrix = configuration["attenuators"]["Matrix"]
        self.assertTrue(
            matrix[1] == "SRM_1155",
            "Invalid matrix. Expected <SRM_1155> got <%s>" % matrix[1])
        cToolConfiguration["usematrix"] = 1
        cToolConfiguration["reference"] = "Fe"
        concentrationsResult, addInfo = cTool.processFitResult( \
                    config=cToolConfiguration,
                    fitresult={"result":result},
                    elementsfrommatrix=False,
                    fluorates = mcaFit._fluoRates,
                    addinfo=True)
        referenceElement = addInfo['ReferenceElement']
        referenceTransitions = addInfo['ReferenceTransitions']
        self.assertTrue(
            referenceElement == "Fe",
            "referenceElement is <%s> instead of <Fe>" % referenceElement)

        # check the Fe concentration is 0.65 +/ 5 %
        self.assertTrue( \
            abs(concentrationsResult["mass fraction"]["Fe Ka"] - 0.65) < 0.03,
            "Invalid Fe Concentration")
        # check the Cr concentration is overestimated (more than 30 %) %
        testValue = concentrationsResult["mass fraction"]["Cr K"]
        self.assertTrue(
            testValue > 0.30,
            "Expected Cr concentration above 0.30 got %.3f" % testValue)

        # chek the sum of concentration of main components is above 1
        # because of neglecting higher order excitations
        elements = ["Cr K", "V K", "Mn K", "Fe Ka", "Ni K"]
        total = 0.0
        for element in elements:
            total += concentrationsResult["mass fraction"][element]
        self.assertTrue(
            total > 1,
            "Sum of concentrations should be above 1 got %.3f" % total)

        # correct for tertiary excitation without a new fit
        cToolConfiguration["usemultilayersecondary"] = 2
        concentrationsResult, addInfo = cTool.processFitResult( \
                    config=cToolConfiguration,
                    fitresult={"result":result},
                    elementsfrommatrix=False,
                    fluorates = mcaFit._fluoRates,
                    addinfo=True)

        # check the Fe concentration is 0.65 +/ 5 %
        self.assertTrue( \
            abs(concentrationsResult["mass fraction"]["Fe Ka"] - 0.65) < 0.03,
            "Invalid Fe Concentration Using Tertiary Excitation")

        # chek the sum of concentration of main components is above 1
        elements = ["Cr K", "Mn K", "Fe Ka", "Ni K"]
        total = 0.0
        for element in elements:
            total += concentrationsResult["mass fraction"][element]
        self.assertTrue(
            total < 1,
            "Sum of concentrations should be below 1 got %.3f" % total)
        # check the Cr concentration is not overestimated (more than 30 %) %
        testValue = concentrationsResult["mass fraction"]["Cr K"]
        self.assertTrue(
            (testValue > 0.18) and (testValue < 0.20),
            "Expected Cr between 0.18 and 0.20 got %.3f" % testValue)

        # perform the fit already accounting for tertiary excitation
        # in order to get the good fundamental parameters
        configuration["concentrations"]['usematrix'] = 1
        configuration["concentrations"]["usemultilayersecondary"] = 2
        mcaFit.setConfiguration(configuration)
        mcaFit.setData(x,
                       y,
                       xmin=configuration["fit"]["xmin"],
                       xmax=configuration["fit"]["xmax"])
        mcaFit.estimate()
        fitResult, result = mcaFit.startFit(digest=1)

        # concentrations
        # fit is already done, calculate the concentrations
        concentrationsConfiguration = configuration["concentrations"]
        cTool = ConcentrationsTool.ConcentrationsTool()
        cToolConfiguration = cTool.configure()
        cToolConfiguration.update(configuration['concentrations'])
        matrix = configuration["attenuators"]["Matrix"]
        self.assertTrue(
            matrix[1] == "SRM_1155",
            "Invalid matrix. Expected <SRM_1155> got <%s>" % matrix[1])
        cToolConfiguration["usematrix"] = 1
        cToolConfiguration["reference"] = "Fe"
        concentrationsResult, addInfo = cTool.processFitResult( \
                    config=cToolConfiguration,
                    fitresult={"result":result},
                    elementsfrommatrix=False,
                    fluorates = mcaFit._fluoRates,
                    addinfo=True)

        # make sure we are not using an internal standard
        # repeat everything using a single layer strategy
        configuration["concentrations"]['usematrix'] = 0
        configuration["concentrations"]['flux'] = addInfo["Flux"]
        configuration["concentrations"]['time'] = addInfo["Time"]
        configuration["concentrations"]['area'] = addInfo["DetectorArea"]
        configuration["concentrations"]['distance'] = \
                                                    addInfo["DetectorDistance"]
        configuration["concentrations"]["usemultilayersecondary"] = 2

        # setup the strategy starting with Fe as matrix
        matrix[1] = "Fe"
        configuration["attenuators"]["Matrix"] = matrix
        configuration["fit"]["strategyflag"] = 1
        configuration["fit"]["strategy"] = "SingleLayerStrategy"
        configuration["SingleLayerStrategy"] = {}
        configuration["SingleLayerStrategy"]["layer"] = "Auto"
        configuration["SingleLayerStrategy"]["iterations"] = 3
        configuration["SingleLayerStrategy"]["completer"] = "-"
        configuration["SingleLayerStrategy"]["flags"] = [
            1, 1, 1, 1, 0, 0, 0, 0, 0, 0
        ]
        configuration["SingleLayerStrategy"]["peaks"] = [
            "Cr K", "Mn K", "Fe Ka", "Ni K", "-", "-", "-", "-", "-", "-"
        ]
        configuration["SingleLayerStrategy"]["materials"] = [
            "Cr", "Mn", "Fe", "Ni", "-", "-", "-", "-", "-"
        ]
        mcaFit = ClassMcaTheory.ClassMcaTheory()
        configuration = mcaFit.configure(configuration)
        mcaFit.setData(x,
                       y,
                       xmin=configuration["fit"]["xmin"],
                       xmax=configuration["fit"]["xmax"])
        mcaFit.estimate()
        fitResult, result = mcaFit.startFit(digest=1)

        # concentrations
        # fit is already done, calculate the concentrations
        concentrationsConfiguration = configuration["concentrations"]
        cTool = ConcentrationsTool.ConcentrationsTool()
        cToolConfiguration = cTool.configure()
        cToolConfiguration.update(configuration['concentrations'])
        concentrationsResult2, addInfo = cTool.processFitResult( \
                    config=cToolConfiguration,
                    fitresult={"result":result},
                    elementsfrommatrix=False,
                    fluorates = mcaFit._fluoRates,
                    addinfo=True)

        # chek the sum of concentration of main components is above 1
        elements = ["Cr K", "Mn K", "Fe Ka", "Ni K"]
        total = 0.0
        for element in elements:
            if element == "Cr K":
                tolerance = 6  # 6 %
            else:
                tolerance = 5  # 5 %
            previous = concentrationsResult["mass fraction"][element]
            current = concentrationsResult2["mass fraction"][element]
            delta = 100 * (abs(previous - current) / previous)
            self.assertTrue(delta < tolerance,
                "Strategy: Element %s discrepancy too large %.1f %%" % \
                  (element.split()[0], delta))
예제 #2
0
파일: XrfTest.py 프로젝트: sjmvm/pymca
    def testTrainingDataFit(self):
        from PyMca5.PyMcaIO import specfilewrapper as specfile
        from PyMca5.PyMcaPhysics.xrf import ClassMcaTheory
        from PyMca5.PyMcaPhysics.xrf import ConcentrationsTool
        from PyMca5.PyMcaIO import ConfigDict
        trainingDataFile = os.path.join(self.dataDir, "XRFSpectrum.mca")
        self.assertTrue(os.path.isfile(trainingDataFile),
                        "File %s is not an actual file" % trainingDataFile)

        sf = specfile.Specfile(trainingDataFile)
        self.assertTrue(
            len(sf) == 2, "Training data not interpreted as two scans")
        self.assertTrue(sf[0].nbmca() == 0,
                        "Training data 1st scan should contain no MCAs")
        self.assertTrue(sf[1].nbmca() == 1,
                        "Training data 1st scan should contain no MCAs")
        y = mcaData = sf[1].mca(1)
        sf = None

        # perform the actual XRF analysis
        configuration = ConfigDict.ConfigDict()
        configuration.readfp(StringIO(cfg))
        mcaFit = ClassMcaTheory.ClassMcaTheory()
        configuration = mcaFit.configure(configuration)
        x = numpy.arange(y.size).astype(numpy.float)
        mcaFit.setData(x,
                       y,
                       xmin=configuration["fit"]["xmin"],
                       xmax=configuration["fit"]["xmax"])
        mcaFit.estimate()
        fitResult, result = mcaFit.startFit(digest=1)

        # fit is already done, calculate the concentrations
        concentrationsConfiguration = configuration["concentrations"]
        cTool = ConcentrationsTool.ConcentrationsTool()
        cToolConfiguration = cTool.configure()
        cToolConfiguration.update(configuration['concentrations'])
        # make sure we are using Co as internal standard
        cToolConfiguration["usematrix"] = 1
        cToolConfiguration["reference"] = "Co"
        concentrationsResult, addInfo = cTool.processFitResult( \
                    config=cToolConfiguration,
                    fitresult={"result":result},
                    elementsfrommatrix=False,
                    fluorates = mcaFit._fluoRates,
                    addinfo=True)
        referenceElement = addInfo['ReferenceElement']
        referenceTransitions = addInfo['ReferenceTransitions']
        self.assertTrue(
            referenceElement == "Co",
            "referenceElement is <%s> instead of <Co>" % referenceElement)
        cobalt = concentrationsResult["mass fraction"]["Co K"]
        self.assertTrue(
            abs(cobalt - 0.0005) < 1.0E-7,
            "Wrong Co concentration %f expected 0.0005" % cobalt)

        # we should get the same result with internal parameters
        cTool = ConcentrationsTool.ConcentrationsTool()
        cToolConfiguration = cTool.configure()
        cToolConfiguration.update(configuration['concentrations'])

        # make sure we are not using an internal standard
        cToolConfiguration['usematrix'] = 0
        cToolConfiguration['flux'] = addInfo["Flux"]
        cToolConfiguration['time'] = addInfo["Time"]
        cToolConfiguration['area'] = addInfo["DetectorArea"]
        cToolConfiguration['distance'] = addInfo["DetectorDistance"]
        concentrationsResult2, addInfo = cTool.processFitResult( \
                    config=cToolConfiguration,
                    fitresult={"result":result},
                    elementsfrommatrix=False,
                    fluorates = mcaFit._fluoRates,
                    addinfo=True)
        referenceElement = addInfo['ReferenceElement']
        referenceTransitions = addInfo['ReferenceTransitions']
        self.assertTrue(
            referenceElement in ["None", "", None],
            "referenceElement is <%s> instead of <None>" % referenceElement)

        for key in concentrationsResult["mass fraction"]:
            internal = concentrationsResult["mass fraction"][key]
            fp = concentrationsResult2["mass fraction"][key]
            delta = 100 * (abs(internal - fp) / internal)
            self.assertTrue(
                delta < 1.0e-5,
                "Error for <%s> concentration %g != %g" % (key, internal, fp))