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
def setSelection(self, symbol=None): if symbol is None: if self.addnone: if qt.qVersion() < '4.0.0': self.setCurrentItem(0) else: self.setCurrentIndex(0) else: idx = self.addnone + Elements.getz(symbol) - 1 if qt.qVersion() < '4.0.0': self.setCurrentItem(idx) else: self.setCurrentIndex(idx)
def continuumEbel(target, e0, e=None, window=None, alphae=None, alphax=None, transmission=None, targetthickness=None, filterlist=None): """ Calculation of X-ray Tube continuum emission spectrum Parameters: ----------- target : list [Symbol, density (g/cm2), thickness(cm)] or atomic ymbol If set to atomic symbol, the program sets density and thickness of 0.1 cm e0 : float Tube Voltage in kV e : float or array of floats Energy of interest. If not given, the program will generate an array of energies from 1 to the given tube voltage minus 1 kV in keV. window : list Tube window [Formula, density, thickness] alphae : float Angle, in degrees, between electron beam and tube target. Normal incidence is 90. alphax : float Angle, in degrees, of X-ray exit beam. Normal exit is 90. transmission : Boolean, default is False If True the X-ray come out of the tube target by the side opposite to the one receiving the exciting electron beam. targetthickness : Target thickness in cm Only considered in transmission case. If not given, the program uses as target thickness the maximal penetration depth of the incident electron beam. filterlist : [list] Additional filters [[Formula, density, thickness], ...] Return: ------- result : Array Spectral flux density. Flux of photons at the given energies in photons/sr/mA/keV/s Reference: H. Ebel, X-Ray Spectrometry 28 (1999) 255-266 Tube voltage from 5 to 50 kV Electron incident angle from 50 to 90 deg. X-Ray take off angle from 90 to 5 deg. """ if type(target) in [type([]), type(list())]: element = target[0] density = target[1] thickness = target[2] else: element = target density = Elements.Element[element]['density'] thickness = 0.1 if e is None: energy = numpy.arange(e0 * 1.0)[1:] elif type(e) == type([]): energy = numpy.array(e, dtype=numpy.float) elif type(e) == numpy.ndarray: energy = numpy.array(e, dtype=numpy.float) else: energy = numpy.array([e], dtype=numpy.float) if alphae is None: alphae = 75.0 if alphax is None: alphax = 15.0 if transmission is None: transmission = False sinalphae = math.sin(math.radians(alphae)) sinalphax = math.sin(math.radians(alphax)) sinfactor = sinalphae / sinalphax z = Elements.getz(element) const = 1.35e+09 x = 1.109 - 0.00435 * z + 0.00175 * e0 # calculate intermediate constants from formulae (4) in Ebel's paper # eta in Ebel's paper m = 0.1382 - 0.9211 / math.sqrt(z) logz = math.log(z) eta = 0.1904 - 0.2236 * logz + 0.1292 * pow(logz, 2) - \ 0.0149 * pow(logz, 3) eta = eta * pow(e0, m) # dephmax? in Ebel's paper p3 = 0.787e-05 * math.sqrt(0.0135 * z) * pow(e0, 1.5) + \ 0.735e-06 * pow(e0, 2) rhozmax = (Elements.Element[element]['mass'] / z) * p3 # print "max depth = ",2 * rhozmax # and finally we get rhoz u0 = e0 / energy logu0 = numpy.log(u0) p1 = logu0 * (0.49269 - 1.09870 * eta + 0.78557 * pow(eta, 2)) p2 = 0.70256 - 1.09865 * eta + 1.00460 * pow(eta, 2) + logu0 rhoz = rhozmax * (p1 / p2) # the term dealing with the photoelectric absorption of the Bremsstrahlung tau = numpy.array( Elements.getMaterialMassAttenuationCoefficients(element, 1.0, energy)['photo']) if not transmission: rhelp = tau * 2.0 * rhoz * sinfactor if len(numpy.nonzero(rhelp <= 0.0)[0]): result = numpy.zeros(rhelp.shape, numpy.float) for i in range(len(rhelp)): if rhelp[i] > 0.0: result[i] = const * z * pow(u0[i] - 1.0, x) * \ (1.0 - numpy.exp(-rhelp[i])) / rhelp[i] else: result = const * z * pow(u0 - 1.0, x) * \ (1.0 - numpy.exp(-rhelp)) / rhelp # the term dealing with absorption in tube's window if window is not None: if window[2] != 0: w = Elements.getMaterialTransmission( window[0], 1.0, energy, density=window[1], thickness=window[2], listoutput=False)['transmission'] result *= w if filterlist is not None: w = 1 for fwindow in filterlist: if fwindow[2] == 0: continue w *= Elements.getMaterialTransmission( fwindow[0], 1.0, energy, density=fwindow[1], thickness=fwindow[2], listoutput=False)['transmission'] result *= w return result # transmission case if targetthickness is None: #d = Elements.Element[target]['density'] d = density ttarget = 2 * rhozmax print( "WARNING target thickness assumed equal to maximum depth of %f cm" % (ttarget / d)) else: #ttarget = targetthickness * Elements.Element[target]['density'] ttarget = targetthickness * density # generationdepth = min(ttarget, 2 * rhozmax) rhelp = tau * 2.0 * rhoz * sinfactor if len(numpy.nonzero(rhelp <= 0.0)[0]): result = numpy.zeros(rhelp.shape, numpy.float) for i in range(len(rhelp)): if rhelp[i] > 0.0: result[i] = const * z * pow(u0[i] - 1.0, x) * \ (numpy.exp(-tau[i] *(ttarget - 2.0 * rhoz[i]) / sinalphax) - \ numpy.exp(-tau[i] * ttarget / sinalphax)) / rhelp[i] else: result = const * z * pow(u0 - 1.0, x) * \ (numpy.exp(-tau *(ttarget - 2.0 * rhoz) / sinalphax) - \ numpy.exp(-tau * ttarget / sinalphax)) / rhelp # the term dealing with absorption in tube's window if window is not None: if window[2] != 0.0: w = Elements.getMaterialTransmission( window[0], 1.0, energy, density=window[1], thickness=window[2] / sinalphax, listoutput=False)['transmission'] result *= w if filterlist is not None: for fwindow in filterlist: if fwindow[2] == 0: continue w = Elements.getMaterialTransmission( fwindow[0], 1.0, energy, density=fwindow[1], thickness=fwindow[2], listoutput=False)['transmission'] result *= w return result
def characteristicEbel(target, e0, window=None, alphae=None, alphax=None, transmission=None, targetthickness=None, filterlist=None): """ Calculation of target characteritic lines and intensities Parameters: ----------- target : list [Symbol, density (g/cm2), thickness(cm)] or atomic ymbol If set to atomic symbol, the program sets density and thickness of 0.1 cm e0 : float Tube Voltage in kV e : float Energy of interest window : list Tube window [Formula, density, thickness] alphae : float Angle, in degrees, between electron beam and tube target. Normal incidence is 90. alphax : float Angle, in degrees, of X-ray exit beam. Normal exit is 90. transmission : Boolean, default is False If True the X-ray come out of the tube target by the side opposite to the one receiving the exciting electron beam. targetthickness : Target thickness in cm Only considered in transmission case. If not given, the program uses as target thickness the maximal penetration depth of the incident electron beam. filterlist : [list] Additional filters [[Formula, density, thickness], ...] Result: list Characteristic lines and intensities in the form [[energy0, intensity0, name0], [energy1, intensity1, name1], ...] Energies in keV Intensities in photons/sr/mA/keV/s """ if type(target) == type([]): element = target[0] density = target[1] thickness = target[2] if targetthickness is None: targetthickness = target[2] else: element = target density = Elements.Element[element]['density'] thickness = 0.1 if alphae is None: alphae = 75.0 if alphax is None: alphax = 15.0 if transmission is None: transmission = False sinalphae = math.sin(math.radians(alphae)) sinalphax = math.sin(math.radians(alphax)) sinfactor = sinalphae / sinalphax z = Elements.getz(element) const = 6.0e+13 # K Shell energy = Elements.Element[element]['binding']['K'] # get the energy of the characteristic lines lines = Elements._getUnfilteredElementDict(element, None, photoweights=True) if 0: # L shell lines will have to be entered directly by the user # L shell lpeaks = [] for label in lines['L xrays']: lpeaks.append([ lines[label]['energy'], lines[label]['rate'], element + ' ' + label ]) lfluo = Elements._filterPeaks(lpeaks, ethreshold=0.020, ithreshold=0.001, nthreshold=6, absoluteithreshold=False, keeptotalrate=True) lfluo.sort() peaklist = [] rays = 'K xrays' if rays in lines.keys(): #K shell for label in lines[rays]: peaklist.append([ lines[label]['energy'], lines[label]['rate'], element + ' ' + label ]) fl = Elements._filterPeaks(peaklist, ethreshold=0.020, ithreshold=0.001, nthreshold=4, absoluteithreshold=False, keeptotalrate=True) fl.sort() if (energy > 0) and (e0 > energy): zk = 2.0 bk = 0.35 else: for i in range(len(fl)): fl[i][1] = 0.00 return fl u0 = e0 / energy logu0 = numpy.log(u0) # stopping factor oneovers = (numpy.sqrt(u0) * logu0 + 2 * (1.0 - numpy.sqrt(u0))) oneovers /= u0 * logu0 + 1.0 - u0 oneovers = 1.0 + 16.05 * numpy.sqrt(0.0135 * z / energy) * oneovers oneovers *= (zk * bk / z) * (u0 * logu0 + 1.0 - u0) # backscattering factor r = 1.0 - 0.0081517 * z + 3.613e-05 * z * z +\ 0.009583 * z * numpy.exp(-u0) + 0.001141 * e0 # Absorption correction # calculate intermediate constants from formulae (4) in Ebel's paper # eta in Ebel's paper m = 0.1382 - 0.9211 / numpy.sqrt(z) logz = numpy.log(z) eta = 0.1904 - 0.2236 * logz + 0.1292 * pow(logz, 2) - 0.0149 * pow( logz, 3) eta = eta * pow(e0, m) # depmax? in Ebel's paper p3 = 0.787e-05 * numpy.sqrt(0.0135 * z) * pow(e0, 1.5) + \ 0.735e-06 * pow(e0, 2) rhozmax = (Elements.Element[element]['mass'] / z) * p3 # and finally we get rhoz p1 = logu0 * (0.49269 - 1.09870 * eta + 0.78557 * pow(eta, 2)) p2 = 0.70256 - 1.09865 * eta + 1.00460 * pow(eta, 2) + logu0 rhoz = rhozmax * (p1 / p2) # the term dealing with the photoelectric absorption energylist = [] for i in range(len(fl)): energylist.append(fl[i][0]) tau = numpy.array( Elements.getMaterialMassAttenuationCoefficients( element, 1.0, energylist)['photo']) if not transmission: rhelp = tau * 2.0 * rhoz * sinfactor w = None if window is not None: if window[2] != 0.0: w = Elements.getMaterialTransmission( window[0], 1.0, energylist, density=window[1], thickness=window[2], listoutput=False)['transmission'] if filterlist is not None: for fwindow in filterlist: if fwindow[2] == 0: continue if w is None: w = Elements.getMaterialTransmission( fwindow[0], 1.0, energylist, density=fwindow[1], thickness=fwindow[2], listoutput=False)['transmission'] else: w *= Elements.getMaterialTransmission( fwindow[0], 1.0, energylist, density=fwindow[1], thickness=fwindow[2], listoutput=False)['transmission'] for i in range(len(fl)): if rhelp[i] > 0.0: rhelp[i] = (1.0 - numpy.exp(-rhelp[i])) / rhelp[i] else: rhelp[i] = 0.0 intensity = const * oneovers * r * Elements.getomegak( element) * rhelp[i] #the term dealing with absorption in tube's window if w is not None: intensity = intensity * w[i] fl[i][1] = intensity * fl[i][1] return fl #transmission case if targetthickness is None: d = density ttarget = 2 * rhozmax print( "WARNING target thickness assumed equal to maximum depth of %f cm" % (ttarget / d)) else: ttarget = targetthickness * density #generationdepth = min(ttarget, 2 * rhozmax) rhelp = tau * 2.0 * rhoz * sinfactor w = None if (window is not None) or (filterlist is not None): if window is not None: if window[2] != 0.0: w = Elements.getMaterialTransmission( window[0], 1.0, energylist, density=window[1], thickness=window[2] / sinalphax, listoutput=False)['transmission'] if filterlist is not None: for fwindow in filterlist: if w is None: w = Elements.getMaterialTransmission( fwindow[0], 1.0, energylist, density=fwindow[1], thickness=fwindow[2], listoutput=False)['transmission'] else: w *= Elements.getMaterialTransmission( fwindow[0], 1.0, energylist, density=fwindow[1], thickness=fwindow[2], listoutput=False)['transmission'] for i in range(len(fl)): if rhelp[i] > 0.0: rhelp[i] = ( numpy.exp(-tau[i] * (ttarget - 2.0 * rhoz) / sinalphax) - numpy.exp(-tau[i] * ttarget / sinalphax)) / rhelp[i] else: rhelp[i] = 0.0 intensity = const * oneovers * r * Elements.getomegak( element) * rhelp[i] if w is not None: intensity = intensity * w[i] fl[i][1] = intensity * fl[i][1] return fl
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 secondary and Monte Carlo correction can be used" raise ValueError(txt) # 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 = 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=secondary) 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=secondary) 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 xrfmcSecondary and (not elementsfrommatrix): xrfmcCorrections = None if 'xrfmc' in fitresult: xrfmcCorrections = fitresult['xrfmc'].get('corrections', None) if xrfmcCorrections is None: if 'xrfmc' in fitresult['result']: xrfmcCorrections = fitresult['result']['xrfmc'].get( 'corrections', None) if xrfmcCorrections is None: # try to see if they were in the configuration if 'xrfmc' in fitresult['result']['config']: xrfmcCorrections = fitresult['result']['config'][ 'xrfmc'].get('corrections', None) if xrfmcCorrections is None: # calculate the corrections xrfmcCorrections = XRFMCHelper.getXRFMCCorrectionFactors( fitresult['result']['config']) if referenceElement is not None: referenceLines = referenceTransitions.split()[0] referenceCorrection = xrfmcCorrections[referenceElement][referenceLines]\ ['correction_factor'][-1] xrfmcCorrections[referenceElement][referenceLines]\ ['correction_factor'][-1] = 1.0 for group in groupsList: item = group.split() element = item[0] lines = item[1] if element in xrfmcCorrections: if element != referenceElement: if lines != referenceLines: xrfmcCorrections[element][lines][ 'correction_factor'][ -1] *= referenceCorrection # now we have to apply the corrections for group in groupsList: item = group.split() element = item[0] lines = item[1] if element in xrfmcCorrections: correction = xrfmcCorrections[element][ item[1]]['correction_factor'][-1] ddict['mass fraction'][group] /= correction 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