Author Topic: fitSpectrum command syntax  (Read 431 times)

Walter

  • Post Doc
  • ***
  • Posts: 11
fitSpectrum command syntax
« on: February 25, 2020, 06:45:07 am »
Hi, in the commands list of dir() I’ve found ‘fitSpectrum’ that’s seems very interesting.

help(fitSpectrum) returns:

Code: [Select]
fitSpectrum(spec, nIter=5)
    Fit spec, an ISpectrumData object, with a series of Gaussian's centered on the characteristic x-ray energies.  spec must define a detector and a StandardComposition in it's properties.

Unfortunately I did not find any other explanation or guide in the documentation section on the official site DTSA-II.

I tried various input for but I always obtain a syntax error, can anyone tell me the correct syntax for this command?

Thank you,

Walter

NicholasRitchie

  • Moderator
  • Professor
  • *****
  • Posts: 37
    • NIST DTSA-II
Re: fitSpectrum command syntax
« Reply #1 on: February 25, 2020, 07:37:31 am »
Well let's see here - Re-acquainting myself with the code it seems that fitSpectrum takes a spectrum with detector and composition information and uses a non-linear algorithm to fit a continuum model and Gaussian peak profiles to the spectrum data. 

spec is a spectrum object.   The easiest way to create a spectrum object is to read one from disk and then use the "ls()" function to determine its Python alias.  A spectrum alias is a variable "s?" where ? is an integer index.

Since the spectrum must be associated with a detector, make sure that you have defined a suitable detector in "File -> Properties" and that it is selected as the "Default Detector" on the left side of the "Spectrum" panel.  (This needs to be done before reading in the spectrum.)

Since the spectrum must also be associated with a composition so the fitting algorithm knows which elements to fit, select the spectrum in the "Spectrum List" and use the "Tools -> Assign material..." menu item to specify the approximate composition (guess if you don't know.)

Now simply
1> ls()
Name   Spectrum
s1   FeNiCrSS
2> r=fitSpectrum(s1)   # Performs the fit assigning the result to r
3> display(r["Brem"])   # Displays the fit continuum spectrum
4> display(r["Char"])    # Displays the fit characteristic portion of the spectrum
5> report(r["Result].toHTML())   # Outputs a result table on the Report tab


This is the Python code behind it all which calls Java code in the EPQ library.


def fitSpectrum(spec, nIter=5, poly=3, fn="mostRecentFit.csv"):
    """fitSpectrum(spec, nIter=5)
    Fit spec, an ISpectrumData object, with a series of Gaussian's centered on the characteristic x-ray energies.  spec must define a detector and a StandardComposition in it's properties."""
    sp = spec.getProperties()
    sf = epq.SpectrumFitter8(sp.getDetector(), sp.getCompositionProperty(epq.SpectrumProperties.StandardComposition), spec)
    rois = sf.getROIS()
    props = sp.getDetector().getCalibration().getProperties()
    # If there is an extended range of energies with characteristic peaks,
    # we should increase the number of fit parameters.
    coeffs = (
            props.getNumericWithDefault(epq.SpectrumProperties.EnergyOffset, 0.0),
            props.getNumericWithDefault(epq.SpectrumProperties.EnergyScale, 10.0),
            props.getNumericWithDefault(epq.SpectrumProperties.EnergyQuadratic, 0.0),
            0.0,
            0.0)
    sf.setEnergyScale(sf.EnergyScaleFunction(coeffs, poly))
    # Fit both Fano factor and noise...
    sf.setResolution(sf.FanoNoiseWidth(6.0))
    # First fit using table weights...
    sf.setMultiLineset(sf.buildWeighted(rois))
    mrFitsFile = None
    try:
        results = sf.compute()
        elmFits = jio.File(App.getReport().getBasePath(), fn)
        mrFitsFile = jio.FileWriter(elmFits, elmFits.exists())
        # mrFitsFile.write(results.tabulateResults())
        for i in range(0, nIter):
            # Refit by adjusting the line weights...
            results = sf.recompute(10.0, 0.3)
        try:
            mrFitsFile.write(results.tabulateResults())
            mrFitsFile.write(results.tabulateResults(sp))
            mrFitsFile.flush()
        except jl.Exception, e1:
            e1.printStackTrace()
    finally:
        if mrFitsFile:
            mrFitsFile.close()
    result = { }
    result["Result"] = results
    result["Spectrum"] = spec
    result["Fit"] = sf.getBestFit()
    result["Char"] = sf.getCharacteristicSpectrum()
    result["Brem"] = sf.getBremsstrahlungSpectrum()
    return result


Walter

  • Post Doc
  • ***
  • Posts: 11
Re: fitSpectrum command syntax
« Reply #2 on: March 26, 2020, 05:03:05 am »
Thank you Nicholas,

Just another short question: what actually is r["Char"] and what is the difference between r["Char"] and r["Fit"]?


Because I tried to fit a FeCr spectrum with (1) the right composition FeCr, (2) partial composition Fe and (3) wrong composition Pm (it has some peaks near to CrKa and FeKa).

in (1) and (2) the Fits are the same since, even if in Char (2) only the Fe is considered and in the Brem (2) the missing Cr peaks are present.

in (1) and (3) the Fit are different (very bad for (3)), even if Char and Brem (1) and (3) are the same.

I noticed that in the Report are present the values coming from Fit

Best,

Walter

jrminter

  • Professor
  • ****
  • Posts: 57
Re: fitSpectrum command syntax
« Reply #3 on: March 27, 2020, 09:51:43 am »
I'm guessing Nicholas is dealing with all the "work from home" fun we are all having with covid-19

The answer to your question was at the bottom of tbe python source code he sent you:

 result["Fit"] = sf.getBestFit()  i.e. the best fit spectrum (the fit to your peaks, given the composition you input)
 result["Char"] = sf.getCharacteristicSpectrum() i.e. the characteristic spectrum (your peaks of interest minus background)
 result["Brem"] = sf.getBremsstrahlungSpectrum()  i.e the getBremsstrahlung spectrum (background)

Hope this helps until everyone is back to normal

Best regards,
John Minter

NicholasRitchie

  • Moderator
  • Professor
  • *****
  • Posts: 37
    • NIST DTSA-II
Re: fitSpectrum command syntax
« Reply #4 on: March 31, 2020, 01:18:50 pm »
Thanks, John.
Yes, I'm stuck at home like so many but grateful to still be healthy and employed.  :)
The r["Brem"] should vary slightly with the elements present due to modeling of the continuum X-rays as they leave the sample.  Otherwise it is mainly a empirical fit based on a quadratic model.

The function attempts to adapt the detector energy calibration, resolution and weights-of-lines (within a range) to best fit a Lifshin-style continuum model and Gaussian characteristic peak model to the unknown spectrum.

r["Brem"] contains the result of the continnum model.
r["Char"] contains the result of the Gaussian characteristic peak fit
r["Fit"] = r["Brem"]+r["Char"]

Nicholas

N