Source code for PyMca5.PyMcaPhysics.xrf.ConcentrationsTool
#/*##########################################################################
#
# The PyMca X-Ray Fluorescence Toolkit
#
# Copyright (c) 2004-2015 European Synchrotron Radiation Facility
#
# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
# the ESRF by the Software group.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#############################################################################*/
__author__ = "V.A. Sole - ESRF Data Analysis"
__contact__ = "sole@esrf.fr"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
import sys
import copy
import numpy
from . import Elements
from .XRFMC import XRFMCHelper
FISX = False
try:
from . import FisxHelper
FISX = True
except ImportError:
print("WARNING: fisx features not available")
[docs]class ConcentrationsConversion(object):
[docs] def getConcentrationsAsHtml(self, concentrations=None):
text = ""
if concentrations is None:
return text
result = concentrations
#the header
if 'mmolar' in result:
mmolarflaglist = [False, True]
else:
mmolarflaglist = [False]
for mmolarflag in mmolarflaglist:
text += "\n"
text += "<H2><a NAME=""%s""></a><FONT color=#009999>" %\
'Concentrations'
if mmolarflag:
text += "%s:" % 'mM Concentrations'
else:
text += "%s:" % 'Concentrations'
text += "</FONT></H2>"
text += "<br>"
labels = ['Element', 'Group', 'Fit Area', 'Sigma Area']
if mmolarflag:
labels += 'mM concentration'
else:
labels += 'Mass fraction'
#the table
if 'layerlist' in result:
if type(result['layerlist']) != type([]):
result['layerlist'] = [result['layerlist']]
for label in result['layerlist']:
labels += [label]
lemmon = ("#%x%x%x" % (255, 250, 205)).upper()
white = '#FFFFFF'
hcolor = ("#%x%x%x" % (230, 240, 249)).upper()
text += "<CENTER>"
text += "<nobr>"
text += '<table width="80%" border="0" cellspacing="1" cellpadding="1" >'
text += "<tr>"
for l in range(len(labels)):
if l < 2:
text += '<td align="left" bgcolor=%s><b>%s</b></td>' %\
(hcolor, labels[l])
elif l == 2:
text += '<td align="center" bgcolor=%s><b>%s</b></td>' %\
(hcolor, labels[l])
else:
text += '<td align="right" bgcolor=%s><b>%s</b></td>' %\
(hcolor, labels[l])
text += "</tr>"
line = 0
for group in result['groups']:
text += ("<tr>")
element, group0 = group.split()
fitarea = "%.6e" % result['fitarea'][group]
sigmaarea = "%.2e" % result['sigmaarea'][group]
area = "%.6e" % result['area'][group]
if mmolarflag:
fraction = "%.4g" % result['mmolar'][group]
else:
fraction = "%.4g" % result['mass fraction'][group]
if 'Expected Area' in labels:
fields = [element, group0, fitarea, sigmaarea, area, fraction]
else:
fields = [element, group0, fitarea, sigmaarea, fraction]
if 'layerlist' in result:
for layer in result['layerlist']:
if result[layer]['mass fraction'][group] < 0.0:
fraction = "Unknown"
else:
if mmolarflag:
fraction = "%.4g" % result[layer]['mmolar'][group]
else:
fraction = "%.4g" % result[layer]['mass fraction'][group]
fields += [fraction]
if line % 2:
color = lemmon
else:
color = white
i = 0
for field in fields:
if (i<2):
text += '<td align="left" bgcolor=%s>%s</td>' % (color, field)
else:
text += '<td align="right" bgcolor=%s>%s</td>' % (color, field)
i += 1
text += '</tr>'
line += 1
text += ("</table>")
text += ("</nobr>")
text += "</CENTER>"
return text
[docs] def getConcentrationsAsAscii(self, concentrations=None):
text = ""
if concentrations is None:
return text
result = concentrations
#the table
if 'mmolar' in result:
mmolarflaglist = [False, True]
else:
mmolarflaglist = [False]
for mmolarflag in mmolarflaglist:
labels = ['Element', 'Group', 'Fit_Area', 'Sigma_Area']
if mmolarflag:
labels += ['mM_Concentration']
else:
labels += ['Mass_fraction']
if 'layerlist' in result:
if type(result['layerlist']) != type([]):
result['layerlist'] = [result['layerlist']]
for label in result['layerlist']:
labels += [label.replace(' ', '')]
for l in labels:
text += "%s " % l
text += ("\n")
for group in result['groups']:
element, group0 = group.split()
fitarea = "%.6e" % result['fitarea'][group]
sigmaarea = "%.2e" % result['sigmaarea'][group]
area = "%.6e" % result['area'][group]
if mmolarflag:
fraction = "%.4g" % result['mmolar'][group]
else:
fraction = "%.4g" % result['mass fraction'][group]
if 'Expected Area' in labels:
fields = [element, group0, fitarea, sigmaarea, area,
fraction]
else:
fields = [element, group0, fitarea, sigmaarea, fraction]
if 'layerlist' in result:
for layer in result['layerlist']:
if result[layer]['mass fraction'][group] < 0.0:
fraction = "Unknown"
else:
if mmolarflag:
fraction = "%.4g" %\
result[layer]['mmolar'][group]
else:
fraction = "%.4g" %\
result[layer]['mass fraction'][group]
fields += [fraction]
for field in fields:
text += '%s ' % (field)
text += '\n'
return text
[docs]class ConcentrationsTool(object):
def __init__(self, config=None, fitresult=None):
self.config = {}
self.config['usematrix'] = 0
self.config['useattenuators'] = 1
self.config['usemultilayersecondary'] = 0
self.config['usexrfmc'] = 0
self.config['flux'] = 1.0E10
self.config['time'] = 1.0
self.config['area'] = 30.0
self.config['distance'] = 10.0
self.config['reference'] = "Auto"
self.config['mmolarflag'] = 0
if config is not None:
self.configure(config)
self.fitresult = fitresult
[docs] def configure(self, ddict=None):
if ddict is None:
ddict = {}
for key in ddict:
if key in self.config.keys():
self.config[key] = ddict[key]
return copy.deepcopy(self.config)
[docs] def processFitResult(self, config=None, fitresult=None,
elementsfrommatrix=False, fluorates=None,
addinfo=False):
# I should check if fit was successful ...
if fitresult is None:
fitresult = self.fitresult
else:
self.fitresult = fitresult
if config is None:
config = self.config
else:
self.config = config
if 'usemultilayersecondary' not in self.config:
self.config['usemultilayersecondary'] = 0
if 'usexrfmc' not in self.config:
self.config['usexrfmc'] = 0
secondary = self.config['usemultilayersecondary']
xrfmcSecondary = self.config['usexrfmc']
if secondary and xrfmcSecondary:
txt = "Only one of built-in fisx secondary and Monte Carlo correction can be used"
raise ValueError(txt)
if secondary and (not FISX):
raise ImportError("Module fisx does not seem to be available")
# get attenuators and matrix from fit
attenuators = []
beamfilters = []
funnyfilters = []
matrix = None
detectoratt = None
multilayer = None
for attenuator in fitresult['result']['config']['attenuators'].keys():
if not fitresult['result']['config']['attenuators'][attenuator][0]:
continue
if attenuator.upper() == "MATRIX":
matrix = fitresult['result']['config']['attenuators'][attenuator][1:4]
alphain = fitresult['result']['config']['attenuators'][attenuator][4]
alphaout = fitresult['result']['config']['attenuators'][attenuator][5]
elif attenuator.upper()[:-1] == "BEAMFILTER":
beamfilters.append(fitresult['result']['config']['attenuators']\
[attenuator][1:])
elif attenuator.upper() == "DETECTOR":
detectoratt = fitresult['result']['config']['attenuators'][attenuator][1:]
else:
if len(fitresult['result']['config']['attenuators'][attenuator][1:]) == 4:
fitresult['result']['config']['attenuators'][attenuator].append(1.0)
if abs(fitresult['result']['config']['attenuators'][attenuator][4]-1.0) > 1.0e-10:
#funny attenuator
funnyfilters.append(fitresult['result']['config']['attenuators']\
[attenuator][1:])
else:
attenuators.append(fitresult['result']['config']['attenuators']\
[attenuator][1:])
if matrix is None:
raise ValueError("Invalid or undefined sample matrix")
if matrix[0].upper() == "MULTILAYER":
layerlist = list(fitresult['result']['config']['multilayer'].keys())
layerlist.sort()
for layer in layerlist:
if fitresult['result']['config']['multilayer'][layer][0]:
if multilayer is None:
multilayer = []
multilayer.append(fitresult['result']['config']['multilayer'][layer][1:])
if not Elements.isValidMaterial(multilayer[-1][0]):
raise ValueError("Material %s is not defined" % multilayer[-1][0])
else:
layerlist = ["Layer0"]
multilayer = [matrix]
if not Elements.isValidMaterial(matrix[0]):
raise ValueError("Material %s is not defined" % matrix[0])
if xrfmcSecondary and (len(layerlist) > 1):
txt = "Multilayer Monte Carlo correction not implemented yet"
raise ValueError(txt)
energyList = fitresult['result']['config']['fit']['energy']
if energyList is None:
raise ValueError("Invalid energy")
if type(energyList) != type([]):
energyList = [energyList]
flagList = [1]
weightList = [1.0]
else:
flagList = fitresult['result']['config']['fit']['energyflag']
weightList = fitresult['result']['config']['fit']['energyweight']
finalEnergy = []
finalWeight = []
finalFlag = []
for idx in range(len(energyList)):
if flagList[idx]:
energy = energyList[idx]
if energy is None:
raise ValueError(\
"Energy %d isn't a valid energy" % idx)
if energy <= 0.001:
raise ValueError(\
"Energy %d with value %f isn't a valid energy" %\
(idx, energy))
if weightList[idx] is None:
raise ValueError(\
"Weight %d isn't a valid weight" % idx)
if weightList[idx] < 0.0:
raise ValueError(\
"Weight %d with value %f isn't a valid weight" %\
(idx, weightList[idx]))
finalEnergy.append(energy)
finalWeight.append(weightList[idx])
finalFlag.append(1)
totalWeight = sum(weightList)
if totalWeight == 0.0:
raise ValueError("Sum of energy weights is 0.0")
weightList = [x / totalWeight for x in finalWeight]
energyList = finalEnergy
flagList = finalFlag
# get elements list from fit, not from matrix
groupsList = fitresult['result']['groups'] * 1
if type(groupsList) != type([]):
groupsList = [groupsList]
todelete = []
for i in range(len(groupsList)):
ele = groupsList[i].split()[0]
if len(ele) > 2:
todelete.append(i)
if len(todelete):
todelete.reverse()
for i in todelete:
del groupsList[i]
elements = []
newelements = []
for group in groupsList:
splitted = group.split()
ele = splitted[0]
newelements.append([Elements.getz(splitted[0]),
splitted[0], splitted[1]])
if len(elements):
if elements[-1] != ele:
elements.append(ele)
else:
elements.append(ele)
newelements.sort()
elements.sort()
if not config['useattenuators']:
attenuators = None
funnyfilters = None
#import time
#t0=time.time()
if elementsfrommatrix:
newelementsList = []
for ilayer in range(len(multilayer)):
pseudomatrix = multilayer[ilayer]
eleDict = Elements.getMaterialMassFractions([pseudomatrix[0]], [1.0])
if eleDict == {}:
raise ValueError(\
"Invalid layer material %s" % pseudomatrix[0])
keys = eleDict.keys()
for ele in keys:
for group in newelements:
if ele == group[1]:
if not group in newelementsList:
newelementsList.append(group)
newelementsList.sort()
fluo0 = Elements.getMultilayerFluorescence(multilayer,
energyList,
layerList=None,
weightList=weightList,
flagList=weightList,
fulloutput=1,
beamfilters=beamfilters * 1,
attenuators=attenuators * 1,
elementsList=newelementsList * 1,
alphain=alphain,
alphaout=alphaout,
cascade=True,
detector=detectoratt,
funnyfilters=funnyfilters * 1,
forcepresent=0,
secondary=False)
fluototal = fluo0[0]
fluolist = fluo0[1:]
else:
if matrix[0].upper() != "MULTILAYER":
multilayer = [matrix * 1]
if fluorates is None:
fluo0 = Elements.getMultilayerFluorescence(multilayer,
energyList,
layerList=None,
weightList=weightList,
flagList=flagList,
fulloutput=1,
beamfilters=beamfilters * 1,
attenuators=attenuators * 1,
elementsList=newelements * 1,
alphain=alphain,
alphaout=alphaout,
cascade=True,
detector=detectoratt,
funnyfilters=funnyfilters * 1,
forcepresent=1,
secondary=False)
else:
fluo0 = fluorates
fluototal = fluo0[0]
fluolist = fluo0[1:]
#I'll need total fluo element by element at some point
#print "getMatrixFluorescence elapsed = ",time.time()-t0
if config['usematrix']:
present = []
referenceLayerDict = {}
materialComposition = []
for ilayer in range(len(multilayer)):
pseudomatrix = multilayer[ilayer] * 1
#get elemental composition from matrix
materialComposition.append(Elements.getMaterialMassFractions([pseudomatrix[0]], [1.0]))
keys = materialComposition[-1].keys()
materialElements = [[Elements.getz(x), x] for x in keys]
materialElements.sort()
for z, key in materialElements:
for ele in elements:
if key == ele:
present.append(key)
if not (ele in referenceLayerDict):
referenceLayerDict[ele] = []
referenceLayerDict[ele].append(ilayer)
if len(present) == 0:
text = "Matrix must contain at least one fitted element\n"
text += "in order to estimate flux and efficiency from it."
raise ValueError(text)
referenceElement = config['reference'].replace(' ', "")
if len(referenceElement) and (referenceElement.upper() != 'AUTO'):
if Elements.isValidFormula(referenceElement):
if len(referenceElement) == 2:
referenceElement = referenceElement.upper()[0] +\
referenceElement.lower()[1]
elif len(referenceElement) == 1:
referenceElement = referenceElement.upper()[0]
if not (referenceElement in elements):
text = "Element %s not among fitted elements" % referenceElement
raise ValueError(text)
elif not (referenceElement in present):
text = "Element %s not among matrix elements" % referenceElement
raise ValueError(text)
referenceLayers = referenceLayerDict[referenceElement]
else:
text = "Element %s not a valid element" % referenceElement
raise ValueError(text)
elif len(present) == 1:
referenceElement = present[0]
referenceLayers = referenceLayerDict[referenceElement]
else:
# how to choose? Best fitted, largest fit area or
# greater concentration? or better to give a weight to
# the different shells, energies , ...?
referenceElement = present[0]
fom = self._figureOfMerit(present[0],fluototal,fitresult)
for key in present:
#if materialComposition[key] > materialComposition[referenceElement]:
# referenceElement = key
newfom = self._figureOfMerit(key,fluototal,fitresult)
if newfom > fom:
fom = newfom
referenceElement = key
referenceLayers = referenceLayerDict[referenceElement]
referenceTransitions = None
for group in groupsList:
item = group.split()
element = item[0]
if element == referenceElement:
transitions = item[1] + " xrays"
if referenceTransitions is None:
referenceTransitions = transitions
referenceGroup = group
elif (referenceTransitions[0] == transitions[0]) and\
(referenceTransitions[0] == 'L'):
# this prevents selecting L1 and selects L3 although
# given the appropriate area, L2 can be a safer choice.
referenceGroup = group
referenceTransitions = transitions
elif referenceTransitions is not None:
break
theoretical = 0.0
for ilayer in referenceLayers:
if elementsfrommatrix:
theoretical += fluolist[ilayer][referenceElement]['rates'][referenceTransitions] * \
fluolist[ilayer][referenceElement]['mass fraction']
else:
theoretical += materialComposition[ilayer][referenceElement] * \
fluolist[ilayer][referenceElement]['rates'][referenceTransitions]
if theoretical <= 0.0:
raise ValueError(\
"Theoretical rate is almost 0.0 Impossible to determine flux")
else:
if (config['distance'] > 0.0) and (config['area'] > 0.0):
#solidangle = config['area']/(4.0 * numpy.pi * pow(config['distance'],2))
radius2 = config['area']/numpy.pi
solidangle = 0.5 * (1.0 - (config['distance']/numpy.sqrt(pow(config['distance'],2)+ radius2)))
else:
solidangle = 1.0
flux = fitresult['result'][referenceGroup]['fitarea'] / (theoretical * solidangle)
else:
referenceElement = None
referenceTransitions = None
#solidangle = config['area']/(4.0 * numpy.pi * pow(config['distance'],2))
radius2 = config['area']/numpy.pi
solidangle = 0.5 * (1.0 - (config['distance']/numpy.sqrt(pow(config['distance'],2)+ radius2)))
flux = config['flux'] * config['time']
#print "OBTAINED FLUX * SOLID ANGLE= ",flux * solidangle
#print "flux * time = ",flux
#print "actual solid angle = ",0.5 * (1.0 - (config['distance']/sqrt(pow(config['distance'],2)+ config['area']/pi)))
#print "solid angle factor= ",solidangle
#ele = 'Pb'
#rays = "L xrays"
#print "theoretical = ",fluototal[ele]['rates'][rays]
#print "expected = ",flux * solidangle * fluototal[ele]['rates'][rays]
#for ilayer in range(len(multilayer)):
# print "ilayer = ",ilayer, "theoretical = ",fluolist[ilayer][ele]['rates'][rays]
# print "ilayer = ",ilayer, "expected = ",flux * solidangle * fluolist[ilayer][ele]['rates'][rays]
ddict = {}
ddict['groups'] = groupsList
ddict['elements'] = elements
ddict['mass fraction'] = {}
if 'mmolarflag' in config:
if config['mmolarflag']:
ddict['mmolar'] = {}
else:
config['mmolarflag'] = 0
ddict['area'] = {}
ddict['fitarea'] = {}
ddict['sigmaarea'] = {}
fluo = fluototal
for group in groupsList:
item = group.split()
element = item[0]
transitions = item[1] + " xrays"
if element in fluo.keys():
if transitions in fluo[element]:
#this SHOULD be with concentration one
theoretical = fluo[element]['rates'][transitions] * 1.0
expected = theoretical * flux * solidangle
concentration = fitresult['result'][group]['fitarea']/expected
else:
theoretical = 0.0
concentration = 0.0
else:
theoretical = 0.0
concentration = 0.0
#ddict['area'][group] = theoretical * flux * solidangle * concentration
ddict['fitarea'][group] = fitresult['result'][group]['fitarea']
ddict['sigmaarea'][group] = fitresult['result'][group]['sigmaarea']
if elementsfrommatrix:
if element in fluo.keys():
ddict['mass fraction'][group] = 1.0 * fluo[element]['mass fraction']
else:
ddict['mass fraction'][group] = 0.0
ddict['area'][group] = theoretical * flux * solidangle *\
ddict['mass fraction'][group]
else:
ddict['mass fraction'][group] = concentration
ddict['area'][group] = theoretical * flux * solidangle
if config['mmolarflag']:
#mM = (mass_fraction * density)/atomic_weight
ddict['mmolar'] [group]= 1000000. *\
(multilayer[0][1] * ddict['mass fraction'][group])/Elements.Element[element]['mass']
#I have the globals/average values now I calculate layer per layer
#if necessary
ddict['layerlist'] = []
if matrix[0].upper() == "MULTILAYER":
ilayer = 0
for layer in layerlist:
if fitresult['result']['config']['multilayer'][layer][0]:
ddict['layerlist'].append(layer)
ddict[layer] = {}
dict2 = ddict[layer]
dict2['groups'] = groupsList
dict2['elements'] = elements
dict2['mass fraction'] = {}
if config['mmolarflag']:
dict2['mmolar'] = {}
dict2['area'] = {}
dict2['fitarea'] = {}
fluo = fluolist[ilayer]
for group in groupsList:
item = group.split()
element = item[0]
transitions = item[1] + " xrays"
if element in fluo.keys():
if transitions in fluo[element]:
theoretical = fluo[element]['rates'][transitions] * 1
expected = theoretical * flux * solidangle
if expected > 0.0:
concentration = fitresult['result'][group]['fitarea']/expected
else:
concentration = -1
else:
theoretical = 0.0
concentration = 0.0
else:
theoretical = 0.0
concentration = 0.0
dict2['fitarea'][group] = 1 * fitresult['result'][group]['fitarea']
if elementsfrommatrix:
if element in fluo.keys():
dict2['mass fraction'][group] = 1 * fluo[element]['mass fraction']
else:
dict2['mass fraction'][group] = 0.0
#I calculate matrix in optimized form,
#so I have to multiply by the mass fraction
dict2['area'][group] = theoretical * flux * solidangle *\
dict2['mass fraction'][group]
else:
dict2['mass fraction'][group] = concentration
dict2['area'][group] = theoretical * flux * solidangle
if config['mmolarflag']:
#mM = (mass_fraction * density)/atomic_weight
dict2['mmolar'][group] = 1000000. *\
(multilayer[ilayer][1] * dict2['mass fraction'][group]) /\
Elements.Element[element]['mass']
#if group == "Pb L":
# print "layer", ilayer,'area ', dict2['area'][group]
# print "layer", ilayer,'mass fraction =', dict2['mass fraction'][group]
ilayer += 1
if elementsfrommatrix:
for group in groupsList:
ddict['area'][group] = 0.0
for layer in ddict['layerlist']:
if group in ddict[layer]['area'].keys():
ddict['area'][group] += ddict[layer]['area'][group]
if (not elementsfrommatrix) and (xrfmcSecondary or secondary):
corrections = None
if xrfmcSecondary:
if 'xrfmc' in fitresult:
corrections = fitresult['xrfmc'].get('corrections', None)
if corrections is None:
if 'xrfmc' in fitresult['result']:
corrections = fitresult['result']['xrfmc'].get('corrections', None)
if corrections is None:
# try to see if they were in the configuration
if 'xrfmc' in fitresult['result']['config']:
corrections = fitresult['result']['config']['xrfmc'].get('corrections',
None)
if corrections is None:
# calculate the corrections
corrections = XRFMCHelper.getXRFMCCorrectionFactors(fitresult['result']['config'])
if not ('xrfmc' in fitresult):
fitresult['xrfmc'] = {}
fitresult['xrfmc']['corrections'] = corrections
elif secondary:
corrections = None
if 'fisx' in fitresult:
corrections = fitresult['fisx'].get('corrections', None)
if corrections is not None:
if fitresult['fisx']['secondary'] != secondary:
# it was calculated with wrong secondary level
corrections = None
if corrections is None:
# try to see if they were in the configuration
# in principle this would be the most appropriate place to be
# unless matrix/configuration has been somehow updated.
if 'fisx' in fitresult['result']['config']:
corrections = fitresult['result']['config']['fisx'].get('corrections',
None)
if corrections is not None:
# check they were corrected with proper secondary level
if fitresult['result']['config']['fisx'].get("secondary", -1) != \
secondary:
corrections = None
if corrections is None:
# calculate the corrections
oldValue = fitresult['result']['config']['concentrations']['usemultilayersecondary']
fitresult['result']['config']['concentrations']['usemultilayersecondary'] = secondary
corrections = FisxHelper.getFisxCorrectionFactorsFromFitConfiguration( \
fitresult['result']['config'],
elementsFromMatrix=False)
fitresult['result']['config']['concentrations']['usemultilayersecondary'] = oldValue
if not ('fisx' in fitresult['result']):
fitresult['fisx'] = {}
fitresult['fisx']['corrections'] = copy.deepcopy(corrections)
fitresult['fisx']['secondary'] = secondary
if referenceElement is not None:
referenceLines = referenceTransitions.split()[0]
referenceCorrection = corrections[referenceElement][referenceLines]\
['correction_factor'][-1]
else:
referenceCorrection = 1.0
# now we have to apply the corrections
for group in groupsList:
item = group.split()
element = item[0]
lines = item[1]
if element in corrections:
if config['mmolarflag']:
if ddict['mass fraction'][group] > 0.0:
conversionFactor = ddict['mmolar'][group] / ddict['mass fraction'][group]
else:
conversionFactor = 1.0
correction = corrections[element][item[1]]['correction_factor'][-1] / \
referenceCorrection
ddict['mass fraction'][group] /= correction
if config['mmolarflag']:
ddict['mmolar'][group] = ddict['mass fraction'][group] * conversionFactor
if (matrix[0].upper() == "MULTILAYER") and (not xrfmcSecondary):
iLayer = 0
for layer in layerlist:
if fitresult['result']['config']['multilayer'][layer][0]:
if config['mmolarflag']:
if dict2['mass fraction'][group] > 0.0:
conversionFactor = dict2['mmolar'][group] / dict2['mass fraction'][group]
else:
conversionFactor = 1.0
dict2 = ddict[layer]
layerKey = "layer %d" % iLayer
correction = corrections[element][item[1]][layerKey] \
['correction_factor'][-1] / referenceCorrection
dict2['mass fraction'][group] /= correction
if config['mmolarflag']:
dict2['mmolar'][group] = dict2['mass fraction'][group] * \
conversionFactor
iLayer += 1
if addinfo:
addInfo = {}
addInfo['ReferenceElement'] = referenceElement
addInfo['ReferenceTransitions'] = referenceTransitions
addInfo['SolidAngle'] = solidangle
if config['time'] > 0.0:
addInfo['Time'] = config['time']
else:
addInfo['Time'] = 1.0
addInfo['Flux'] = flux / addInfo['Time']
addInfo['I0'] = flux
addInfo['DetectorDistance'] = config['distance']
addInfo['DetectorArea'] = config['area']
return ddict , addInfo
else:
return ddict
def _figureOfMerit(self, element, fluo, fitresult):
weight = 0.0
for transitions in fluo[element]['rates'].keys():
if fluo[element]['rates'][transitions] > 0.0:
if (transitions[0] == "K") and (Elements.getz(element) > 18):
factor = 2.0
elif (transitions[0] == "L") and (Elements.getz(element) > 54):
factor = 1.5
else:
factor = 1.0
group = element + " " + transitions.split()[0]
if group in fitresult['result']['groups']:
fitarea = fitresult['result'][group]['fitarea']
weightHelp = fitarea * fluo[element]['rates'][transitions] * factor * \
fluo[element]['mass fraction']
if weightHelp > weight:
weight = weightHelp
return weight
[docs]def main():
import sys
import getopt
from PyMca5.PyMcaIO import ConfigDict
if len(sys.argv) > 1:
options = ''
longoptions = ['flux=', 'time=', 'area=', 'distance=',
'attenuators=', 'usematrix=']
tool = ConcentrationsTool()
opts, args = getopt.getopt(
sys.argv[1:],
options,
longoptions)
config = tool.configure()
for opt, arg in opts:
if opt in ('--flux'):
config['flux'] = float(arg)
elif opt in ('--area'):
config['area'] = float(arg)
elif opt in ('--time'):
config['time'] = float(arg)
elif opt in ('--distance'):
config['distance'] = float(arg)
elif opt in ('--attenuators'):
config['useattenuators'] = int(float(arg))
elif opt in ('--usematrix'):
config['usematrix'] = int(float(arg))
tool.configure(config)
filelist = args
for filename in filelist:
d = ConfigDict.ConfigDict()
d.read(filename)
for material in d['result']['config']['materials'].keys():
Elements.Material[material] =\
copy.deepcopy(d['result']['config']['materials'][material])
print(tool.processFitResult(fitresult=d, elementsfrommatrix=True))
else:
print("Usage:")
print("ConcentrationsTool [--flux=xxxx --area=xxxx] fitresultfile")
if __name__ == "__main__":
main()