예제 #1
0
    def FitProcessSpectrum(self, pymca_config, spectrum):
        advancedFit = ClassMcaTheory.McaTheory(config=pymca_config)
        advancedFit.enableOptimizedLinearFit()
        mfTool = ConcentrationsTool(pymca_config)
        tconf = mfTool.configure()

        advancedFit.config['fit']['use_limit'] = 1
        advancedFit.setData(y=spectrum)
        advancedFit.estimate()

        fitresult, tmpresult = advancedFit.startfit(digest=1)
        tmpresult = advancedFit.imagingDigestResult()

        temp = {}
        temp['fitresult'] = fitresult
        temp['result'] = tmpresult
        for bcts, pk in zip(self.BckndCounts, self.peaks_quant):
            tmpresult[pk]['fitarea'] -= bcts
        temp['result']['config'] = advancedFit.config
        tconf.update(advancedFit.configure()['concentrations'])
        conc = mfTool.processFitResult(config=tconf,
                                       fitresult=temp,
                                       elementsfrommatrix=False,
                                       fluorates=advancedFit._fluoRates)

        calc_mf = numpy.float32(
            [conc['mass fraction'][pk] for pk in self.peaks_quant])
        return calc_mf, tmpresult
예제 #2
0
 def __init__(self):
     self.mcafit = ClassMcaTheory.McaTheory()
     self.ctool = ConcentrationsTool.ConcentrationsTool()
     self.app = None
예제 #3
0
def PerformFit(
    filelist,
    cfgfile,
    energies,
    mlines={},
    norm=None,
    fast=False,
    addhigh=0,
    prog=None,
    plot=False,
):
    """Fit XRF spectra in batch with changing primary beam energy.

    Args:
        filelist(list(str)|np.array): spectra to fit
        cfgfile(str): configuration file to use
        energies(np.array): primary beam energies
        mlines(Optional(dict)): elements (keys) which M line group must be replaced by some M subgroups (values)
        norm(Optional(np.array)): normalization array
        fast(Optional(bool)): fast fitting (linear)
        addhigh(Optional(number)): add higher energy
        prog(Optional(timing.ProgessLogger)): progress object
        plot(Optional(bool))
    Returns:
        dict: {label:nenergies x nfiles,...}
    """

    # Load data
    # Each spectrum (each row) in 1 edf file is acquired at a different energy
    if isinstance(filelist, list):
        dataStack = EDFStack.EDFStack(filelist, dtype=np.float32).data
    else:
        dataStack = filelist

    nfiles, nenergies, nchannels = dataStack.shape

    # MCA channels
    xmin = 0
    xmax = nchannels - 1
    x = np.arange(nchannels, dtype=np.float32)

    # Energies
    if hasattr(energies, "__iter__"):
        if len(energies) == 1:
            energies = [energies[0]] * nenergies
        elif len(energies) != nenergies:
            raise ValueError(
                "Expected {} energies ({} given)".format(nenergies, len(energies))
            )
    else:
        energies = [energies] * nenergies

    # Normalization
    if norm is None:
        norm = [1] * nenergies
    else:
        if hasattr(norm, "__iter__"):
            if len(norm) == 1:
                norm = [norm[0]] * nenergies
            elif len(norm) != nenergies:
                raise ValueError(
                    "Expected {} normalization values ({} given)".format(
                        nenergies, len(norm)
                    )
                )
        else:
            norm = [norm] * nenergies

    # Prepare plot
    if plot:
        fig, ax = plt.subplots()

    # Prepare fit
    # ClassMcaTheory.DEBUG = 1
    mcafit = ClassMcaTheory.McaTheory()
    try:
        mcafit.useFisxEscape(True)
    except:
        pass
    if fast:
        mcafit.enableOptimizedLinearFit()
    else:
        mcafit.disableOptimizedLinearFit()
    cfg = mcafit.configure(ReadPyMcaConfigFile(cfgfile))

    # Fit at each energy
    if prog is not None:
        prog.setnfine(nenergies * nfiles)

    ret = {}
    for j in range(nenergies):
        # Prepare fit with this energy
        AdaptPyMcaConfig(cfg, energies[j], mlines=mlines, fast=fast, addhigh=addhigh)
        mcafit.configure(cfg)

        # Fit all spectra with this energy
        for i in range(nfiles):
            # Data to fit
            y = dataStack[i, j, :].flatten()
            mcafit.setData(x, y, xmin=xmin, xmax=xmax)

            # Initial parameter estimates
            mcafit.estimate()

            # Fit
            fitresult = mcafit.startfit(digest=0)

            # Extract result
            if plot:
                mcafitresult = mcafit.digestresult()
                ax.cla()

                if (
                    plot == 2
                    or not any(np.isfinite(np.log(mcafitresult["ydata"])))
                    or not any(mcafitresult["ydata"] > 0)
                ):
                    ax.plot(mcafitresult["energy"], mcafitresult["ydata"])
                    ax.plot(mcafitresult["energy"], mcafitresult["yfit"], color="red")
                else:
                    ax.semilogy(mcafitresult["energy"], mcafitresult["ydata"])
                    ax.semilogy(
                        mcafitresult["energy"], mcafitresult["yfit"], color="red"
                    )
                    ax.set_ylim(
                        ymin=np.nanmin(
                            mcafitresult["ydata"][np.nonzero(mcafitresult["ydata"])]
                        )
                    )
                ax.set_title("Primary energy: {} keV".format(energies[j]))
                ax.set_xlabel("Energy (keV)")
                ax.set_ylabel("Intensity (cts)")
                plt.pause(0.0001)
            else:
                mcafitresult = mcafit.imagingDigestResult()

            # Store result
            for k in mcafitresult["groups"]:
                if k not in ret:
                    ret[k] = np.zeros(
                        (nenergies, nfiles), dtype=type(mcafitresult[k]["fitarea"])
                    )
                ret[k][j, i] = mcafitresult[k]["fitarea"] / norm[j]

            if "chisq" not in ret:
                ret["chisq"] = np.zeros((nenergies, nfiles), dtype=type(mcafit.chisq))
            ret["chisq"][j, i] = mcafit.chisq

        # Print progress
        if prog is not None:
            prog.ndonefine(nfiles)
            prog.printprogress()

    return ret