Author Topic: quantifying a perfect detector  (Read 3064 times)

Ben Buse

  • Professor
  • ****
  • Posts: 499
quantifying a perfect detector
« on: December 21, 2017, 04:28:28 AM »
Hi I've created simulated spectra using a perfect detector, is it possible to quantify them.

The code and using is:

Perfect detector
Code: [Select]
det=epq.Detector.EDSDetector.createPerfectDetector(4096, 10.0, [0.040,0,-0.008])
Quantify
Code: [Select]
res = {}
for unk in unks:
res[unk]=dtsa2.quantify(unk, stds)

But I get the error
Code: [Select]
res[unk]=dtsa2.quantify(unk, stds)
  File "C:\Users\glxbb\AppData\Local\NIST\DTSA-II_Iona 2015-11-12\Lib\dtsa2\__init__.py", line 1254, in quantify
    return qus.compute(unknown)
at gov.nist.microanalysis.EPQLibrary.FilteredSpectrum.compute(FilteredSpectrum.java:79)
at gov.nist.microanalysis.EPQLibrary.FilteredSpectrum.compute(FilteredSpectrum.java:42)
at gov.nist.microanalysis.EPQLibrary.FilteredSpectrum.computeFilteredSpectrum(FilteredSpectrum.java:96)
at gov.nist.microanalysis.EPQLibrary.FilteredSpectrum.getFilteredData(FilteredSpectrum.java:199)
at gov.nist.microanalysis.EPQLibrary.FilterFit.perform(FilterFit.java:243)
at gov.nist.microanalysis.EPQLibrary.FilterFit.updateUnknown(FilterFit.java:514)
at gov.nist.microanalysis.EPQLibrary.FilterFit.getKRatios(FilterFit.java:403)
at gov.nist.microanalysis.EPQLibrary.QuantifyUsingStandards.compute(QuantifyUsingStandards.java:444)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)

java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsException: 0

Any ideas? The complete code is
Code: [Select]
import dtsa2 as dtsa2
import dtsa2.mcSimulate3 as mc3

test = {}

volt = 15, 10

for x in volt:

det=epq.Detector.EDSDetector.createPerfectDetector(4096, 10.0, [0.040,0,-0.008]) # Replace with your detector's name
nE = 1000 # Number of electrons simulated
e0 = x # kV using volt loop - 1st 15kV, then 10 kV

rhoAg = 10.49

s316 = epq.Material(epq.Composition(map(dtsa2.element,["Mo","Fe","Ni","Cr","Mn"],),[0.026,0.67,0.126,0.17,0.017],"316H"),epq.ToSI.gPerCC(8)) #ToSi converts density g/cc to kg/m3, composition as mass fraction
sAg = epq.Material(epq.Composition(map(dtsa2.element,["Ag"],),[1],"Ag coat"),epq.ToSI.gPerCC(10.5))
stdMo = dtsa2.material("Mo",10.2)
stdFe = dtsa2.material("Fe",7.86)
stdNi = dtsa2.material("Ni",8.9)
stdCr = dtsa2.material("Cr",7.19)
stdMn = dtsa2.material("Mn",7.43)

range = dtsa2.electronRange(s316,e0,density=None)

film = {}
film[1] = [sAg, 0.000000005],[s316, 0.000010] # 0.000005000 = 5 um 0.000010 = 10um Configuring multi-layers composition and thickness
film[2] = [sAg, 0.000000010],[s316, 0.000010] # 0.000000050 = 0.05 um
film[3] = [sAg, 0.000000020],[s316, 0.000010]

xtraP = {}
xtraP = {"Characteristic Accumulator":True, "Char Fluor Accumulator":True, "Brem Fluor Accumulator":True}
xtraP.update(mc3.configureOutput(DefaultOutput))
xtraP.update(mc3.configurePhiRhoZ(1.5*range))
xtraP.update(mc3.configureEmissionImages(mc3.suggestTransitions("SiFeSNaKO",e0), 1.5*range, size = 512))
xtraP.update(mc3.configureTrajectoryImage(1.5*range, size = 512))
xtraP.update(mc3.configureOutput('O:\Documents\dtsa2_script_data1')) # Change to output folder
print xtraP
resF = {}
for fil in film:
resF[fil] = mc3.multiFilm(film[fil], det,e0=e0, nTraj=nE, dose=500.0, sf=True, bf=True,xtraParams=xtraP)
#resF[fil].save("%s/%s.msa" % ( 'O:\Documents\dtsa2_script_data1', resF[fil] )) # change to output folder
resF[fil].display()

STDspecs = (stdMo, stdFe, stdNi, stdCr, stdMn, sAg)

specs = {}
for mat in STDspecs:
specs[mat] = mc3.simulate(mat, det,e0=e0, nTraj=nE, dose=500.0, sf=True, bf=True,xtraParams=xtraP)
#specs[mat].save("%s/%s.msa" % ( DefaultOutput, specs[mat] ))
    specs[mat].display()

unks = ( resF[1], resF[2], resF[3])
stds = {"Mo" : specs[stdMo],"Fe" : specs[stdFe],"Ni" : specs[stdNi],"Cr" : specs[stdCr],"Mn" : specs[stdMn],"Ag" : specs[sAg] }

res = {}
for unk in unks:
res[unk]=dtsa2.quantify(unk, stds)

test[x] = unks
tabulate(unks, withErrs=False,prop=epq.SpectrumProperties.KRatios,precision=4)
tabulate(unks, withErrs=True,precision=2)

for x in volt:
print x
tabulate(test[x], withErrs=True,prop=epq.SpectrumProperties.KRatios,precision=4)
tabulate(test[x], withErrs=True,precision=2)

Thanks

Ben

« Last Edit: December 21, 2017, 08:23:04 AM by John Donovan »

Nicholas Ritchie

  • Moderator
  • Professor
  • *****
  • Posts: 155
    • NIST DTSA-II
Re: quantifying a perfect detector
« Reply #1 on: December 21, 2017, 05:04:14 AM »
Short answer: no

Longer answer: The filter fitting process assumes a tophat filter that has the same approximate width as the detector resolution.  A "perfect detector" has essentially zero linewidth.  The Fiori equation relating x-ray energy to detector linewidth is based on the physics of a silicon detector.  It fails with a square root of a negative number when the resolution is better than physics will allow.  So there are a handful of assumptions which are built into the algorithm that fail for "perfect detectors".

Alternative:  Use the peak integration functions (in SpectrumUtils) to compute peak areas and from the area, the k-ratio.  Plug these k-ratios into the KRatioToComposition class.
« Last Edit: December 21, 2017, 08:22:09 AM by John Donovan »
"Do what you can, with what you have, where you are"
  - Teddy Roosevelt