def materialSignal(self, txt): txt = str(txt) if Elements.isValidFormula(txt): if DEBUG: print("validFormula") elementDict = Elements.getMaterialMassFractions([txt], [1.0]) elif Elements.isValidMaterial(txt): if DEBUG: print("ValidMaterial") elementDict = Elements.getMaterialMassFractions([txt], [1.0]) else: if DEBUG: print("to be defined") msg=qt.QMessageBox.information(self, "Invalid Material %s" % txt, "The material %s is not a valid Formula " \ "nor a valid Material.\n" \ "Please use the material editor to define materials" % txt) self.materialWidget.setEditText(self._lastMaterial) if self.materialEditor.isHidden(): self.materialEditor.show() return # We have to update the possible elements elements = list(elementDict.keys()) self.updateElementsWidget(elements)
def _referenceLineSlot(self, ddict): if ddict['event'] == "returnPressed": current = str(self.referenceLine.text()) current = current.replace(' ', '') if (current == '') or (current.upper() == 'AUTO'): pass elif len(current) == 2: current = current.upper()[0] + current.lower()[1] elif len(current) == 1: current = current.upper()[0] else: self.referenceLine.setText('Auto') msg = qt.QMessageBox(self.referenceLine) msg.setIcon(qt.QMessageBox.Critical) msg.setText("Invalid Element %s" % current) msg.exec_() self.referenceLine.setFocus() return if (current == '') or (current.upper() == 'AUTO'): self.referenceLine.setText('Auto') self._mySignal() elif not Elements.isValidFormula(current): self.referenceLine.setText('Auto') msg = qt.QMessageBox(self.referenceLine) msg.setIcon(qt.QMessageBox.Critical) msg.setText("Invalid Element %s" % current) msg.exec_() self.referenceLine.setFocus() else: self.referenceLine.setText(current) self._mySignal()
def setParameters(self, ddict=None): if ddict is None: ddict = {} key = "material" if key in ddict: material = ddict['material'] if Elements.isValidMaterial(material): self.materialWidget.setEditText(material) self.materialSignal(material) else: raise ValueError("Invalid Material %s" % material) key = "element" if key in ddict: ele = ddict[key] for i in range(self.elementWidget.count()): if str(self.elementWidget.itemText(i)).split("(")[0] == ele: self.elementWidget.setCurrentIndex(i) self.elementSignal(ele) key = "edge" if key in ddict: shellList = ["K", "L1", "L2", "L3", "M1", "M2", "M3", "M4", "M5"] idx = shellList.index(ddict[key]) else: idx = 0 self.edgeWidget.setCurrentIndex(idx) self.edgeSignal(idx) key = "energy" if key in ddict: energy = ddict[key] self.energyWidget.setText("%.2f" % energy)
def FindXrays(elsym, energy=60.0, minenergy=1.0, maxenergy=35.0, minrate=0.00010): xr=['K', 'L', 'M'] # chosenxr=[] # chosenxren=[] foundpeaks=[] allpeaksdictlist=[] eltr_quantels=[] for ele in elsym: ElDict={} PyMEl._updateElementDict(ele, ElDict, energy=energy, minenergy=minenergy, minrate=minrate) xray_en_rate=[[x, ElDict[tr]['energy'], ElDict[tr]['rate']] for x in xr for tr in ElDict['%s xrays' %x] if ElDict[tr]['energy']<maxenergy] xraytypes=set([xer[0] for xer in xray_en_rate]) totyieldlist=[] eltrlist=[] for xt in xraytypes: totyield=numpy.float32([v for k, v in PyMEl.Element[ele].iteritems() if k.startswith('omega'+xt.lower())]).sum() totyieldlist+=[totyield] en_rate=[[xer[1], xer[2]] for xer in xray_en_rate if xer[0]==xt] en_rate=numpy.float32(en_rate) enofmaxrate=en_rate[numpy.argmax(en_rate[:, 1]), 0] eltrlist+=[' '.join((ele, xt))] dt={} dt['el']=ele dt['tr']=xt dt['eltr']=' '.join((ele, xt)) dt['repen']=enofmaxrate dt['totyield']=totyield allpeaksdictlist+=[dt] # if len(xraytypes)>1: # tempstr=' and '.join(list(xraytypes)) # print 'XRF ANALYSIS PROBLEM: ', tempstr, ' transitions can be fit but only one will be chosen for', ele if len(xraytypes)==0: print 'XRF ANALYSIS PROBLEM: no valid transitions could be found for ', ele foundpeaks+=[False] else: foundpeaks+=[True] eltr_quantels+=[eltrlist[numpy.argmax(numpy.float32(totyieldlist))]] # xray_en_rate=sorted(xray_en_rate, key=operator.itemgetter(2), reverse=True) # print xray_en_rate # chosenxr+=[' '.join((ele, xray_en_rate[0][0]))] # chosenxren+=[xray_en_rate[0][1]] # return chosenxr, chosenxren, foundpeaks return allpeaksdictlist, eltr_quantels, foundpeaks
def __init__(self, parent=None, name="Elements Info"): qt.QWidget.__init__(self, parent) self.setWindowTitle(name) layout = qt.QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) self.energyValue = None self.splitter = qt.QSplitter(self) layout.addWidget(self.splitter) self.splitter.setOrientation(qt.Qt.Horizontal) self.table = QPeriodicTable(self.splitter) self.html = ElementHtml.ElementHtml() self.infoWidget = None self.table.setMinimumSize(500, 400) self.table.sigElementClicked.connect(self.elementClicked) self.lastElement = None Elements.registerUpdate(self._updateCallback)
def materialSignal(self, txt): txt = str(txt) if Elements.isValidFormula(txt): _logger.debug("validFormula") elementDict = Elements.getMaterialMassFractions([txt], [1.0]) elif Elements.isValidMaterial(txt): _logger.debug("ValidMaterial") elementDict = Elements.getMaterialMassFractions([txt], [1.0]) else: _logger.debug("Material to be defined") msg=qt.QMessageBox.information(self, "Invalid Material %s" % txt, "The material %s is not a valid Formula " \ "nor a valid Material.\n" \ "Please use the material editor to define materials" % txt) self.materialWidget.setEditText(self._lastMaterial) if self.materialEditor.isHidden(): self.materialEditor.show() return # We have to update the possible elements elements = list(elementDict.keys()) self.updateElementsWidget(elements)
def _energySlot(self): string = str(self.energy.text()) if len(string): try: value = float(string) except: msg=qt.QMessageBox(self.energy) msg.setIcon(qt.QMessageBox.Critical) msg.setText("Invalid Float") msg.exec_() self.energy.setFocus() return if self.energyValue is not None: if value != self.energyValue: self.energyValue = value Elements.updateDict(energy=value) else: self.energyValue = value Elements.updateDict(energy=value) self.energy.setPaletteBackgroundColor(qt.QColor('white')) self.infoWidget.setFocus() else: self.energyValue = None self.energy.setText("")
def _energySlot(self): string = str(self.energy.text()) if len(string): try: value = float(string) except: msg = qt.QMessageBox(self.energy) msg.setIcon(qt.QMessageBox.Critical) msg.setText("Invalid Float") msg.exec_() self.energy.setFocus() return if self.energyValue is not None: if value != self.energyValue: self.energyValue = value Elements.updateDict(energy=value) else: self.energyValue = value Elements.updateDict(energy=value) self.energy.setPaletteBackgroundColor(qt.QColor('white')) self.infoWidget.setFocus() else: self.energyValue = None self.energy.setText("")
def _mySlot(self, ddict): if ddict['event'] == "returnPressed": current = str(self.currentText()) current = current.replace(' ', '') if (current == '') or (current.upper() == 'AUTO'): pass elif len(current) == 2: current = current.upper()[0] + current.lower()[1] elif len(current) == 1: current = current.upper()[0] else: msg = qt.QMessageBox(self._lineEdit) msg.setIcon(qt.QMessageBox.Critical) msg.setText("Invalid Element %s" % current) msg.exec_() self._lineEdit.setFocus() if not Elements.isValidFormula(current): msg = qt.QMessageBox(self._lineEdit) msg.setIcon(qt.QMessageBox.Critical) msg.setText("Invalid Element %s" % current) msg.exec_() self._lineEdit.setFocus() else: self.setCurrentText(current)
def correctNormalizedSpectrum(self, energy0, spectrum): """ """ element = self._configuration['XAS']['element'] material = self._configuration['XAS'].get('material', element) edge = self._configuration['XAS']['edge'] alphaIn, alphaOut = self._configuration['XAS']['angles'] edgeEnergy = Elements.Element[element]['binding'][edge] userEdgeEnergy = self._configuration['XAS'].get('energy', edgeEnergy) energy = numpy.array(energy0, dtype=numpy.float64) #PyMca data ar in keV but XAS data are usually in eV if 0.5 * (energy[0] + energy[-1]) / edgeEnergy > 100: # if the user did not do stupid things most likely # the energy was given in eV energy *= 0.001 if userEdgeEnergy / edgeEnergy > 100: userEdgeEnergy *= 0.001 # forget about multilayers for the time being # Elements.getMaterialMassFractions(materialList, massFractionsList) massFractions = Elements.getMaterialMassFractions([material], [1.0]) # calculate the total mass attenuation coefficients at the given energies # exciting the given element shell and not exciting it EPDL = Elements.PyMcaEPDL97 totalCrossSection = 0.0 totalCrossSectionBackground = 0.0 for ele in massFractions.keys(): # make sure EPDL97 respects the Elements energies if EPDL.EPDL97_DICT[ele]['original']: EPDL.setElementBindingEnergies( ele, Elements.Element[ele]['binding']) if ele == element: # make sure we respect the user energy if abs(userEdgeEnergy - edgeEnergy) > 0.01: newBinding = Elements.Element[ele]['binding'] newBinding[edge] = userEdgeEnergy try: EPDL.setElementBindingEnergies(ele, newBinding) crossSections = EPDL.getElementCrossSections( ele, energy) EPDL.setElementBindingEnergies( ele, Elements.Element[ele]['binding']) except: EPDL.setElementBindingEnergies( ele, Elements.Element[ele]['binding']) raise else: crossSections = EPDL.getElementCrossSections(ele, energy) else: crossSections = EPDL.getElementCrossSections(ele, energy) total = numpy.array(crossSections['total']) tmpFloat = massFractions[ele] * total totalCrossSection += tmpFloat if ele != element: totalCrossSectionBackground += tmpFloat else: edgeCrossSections = numpy.array(crossSections[edge]) muSampleJump = massFractions[ele] * edgeCrossSections totalCrossSectionBackground += massFractions[ele] *\ (total - edgeCrossSections) # calculate the mass attenuation coefficient of the sample at the fluorescent energy # assume we are detecting the main fluorescence line of the element shell if edge == 'K': rays = Elements.Element[element]["Ka xrays"] elif edge[0] == 'L': rays = Elements.Element[element][edge + " xrays"] elif edge[0] == 'M': rays = [] for transition in Elements.Element[element]['M xrays']: if transition.startswith(edge): rays.append(transition) lineList = [] for label in rays: ene = Elements.Element[element][label]['energy'] rate = Elements.Element[element][label]['rate'] lineList.append([ene, rate, label]) # whithin 50 eV lines considered the same lineList = Elements._filterPeaks(lineList, ethreshold=0.050) # now take the returned line with the highest intensity fluoLine = lineList[0] for line in lineList: if line[1] > fluoLine[1]: fluoLine = line # and calculate the sample total mass attenuation muTotalFluorescence = 0.0 for ele in massFractions.keys(): crossSections = EPDL.getElementCrossSections(ele, fluoLine[0]) muTotalFluorescence += massFractions[ele] * crossSections['total'][ 0] #define some convenience variables sinIn = numpy.sin(numpy.deg2rad(alphaIn)) sinOut = numpy.sin(numpy.deg2rad(alphaOut)) g = sinIn / sinOut if 1: # thick sample idx = numpy.where(muSampleJump > 0.0)[0][0] muSampleJump[0:idx] = muSampleJump[idx] ALPHA = g * (muTotalFluorescence / muSampleJump ) + totalCrossSectionBackground / muSampleJump return (spectrum * ALPHA) / (1 + ALPHA - spectrum) elif 1: # all samples (to be tested) d = thickness * density idx = numpy.where(muSampleJump > 0.0)[0][0] muSampleJump[0:idx] = muSampleJump[idx] ALPHA = g * (muTotalFluorescence / muSampleJump ) + totalCrossSectionBackground / muSampleJump thickTarget0 = (spectrum * ALPHA) / (1 + ALPHA - spectrum) # Iterate to find the solution x = spectrum t = (ALPHA + 1) * d * muSampleJump / sinIn if t.max() < 0.001: A = 1 - t else: A = numpy.exp(-t) t = (ALPHA * d * muSampleJump / sinIn) if t.max() < 0.001: B = 1.0 - t else: B = numpy.exp(-t) delta = 10.0 i = 0 while (delta > 1.0e-5) and (i < 30): old = x x = thickTarget0 * (1.0 - A) / \ (1.0 - B * numpy.exp(- x * d * muSampleJump/sinIn)) delta = numpy.abs(x - old).max() i += 1 return x else: thickness = 1.0 density = 1.0e-6 # FORMULA Booth and Bridges ALPHA = g * muTotalFluorescence + totalCrossSection tmpFloat0 = density * thickness * ALPHA / sinIn tmpFloat1 = numpy.exp(-tmpFloat0) BETA = (muSampleJump * tmpFloat0) * tmpFloat1 GAMMA = 1.0 - tmpFloat1 b = GAMMA * (ALPHA - muSampleJump * spectrum + BETA) discriminant = b * b + 4 * ALPHA * BETA * GAMMA * (spectrum - 1.0) return 1 + (-b + numpy.sqrt(discriminant)) / (2 * BETA)
def gethtml(self, element=None): if element is None: element = self.element if element is None: return "" ele = element #text="<center><b><font color=red size=5>Summary</font></b></center>" text = "" if ele not in Elements.Element.keys(): text += "<br><b><font color=blue size=4>Unknown Element</font></b>" return text symbol = Elements.getsymbol(Elements.getz(ele)) omegak = Elements.Element[ele]['omegak'] omegal = [ Elements.Element[ele]['omegal1'], Elements.Element[ele]['omegal2'], Elements.Element[ele]['omegal3'] ] omegam = [ Elements.Element[ele]['omegam1'], Elements.Element[ele]['omegam2'], Elements.Element[ele]['omegam3'], Elements.Element[ele]['omegam4'], Elements.Element[ele]['omegam5'] ] #text+="<center> text += "<br><b><font color=blue size=4>Element Info</font></b>" #text+="</center>" if 0: text += "<br><b><font size=3>Name = %s</font></b>" % Elements.Element[ ele]['name'] text += "<br><b><font size=3>Symbol = %s</font></b>" % symbol text += "<br><b><font size=3>At. Number = %d</font></b>" % Elements.Element[ ele]['Z'] text += "<br><b><font size=3>At. Weight = %.5f</font></b>" % Elements.Element[ ele]['mass'] text += "<br><b><font size=3>Density = %.5f</font></b>" % Elements.Element[ ele]['density'] else: hcolor = 'white' finalcolor = 'white' text += "<nobr><table>" #symbol text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>Symbol</font></b>" text += "</td>" text += '<td align="center" bgcolor="%s">' % finalcolor text += "<b><font size=3>=</font></b>" text += "</td>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%s </font></b>" % symbol text += "</td>" #Z text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>At. Number</font></b>" text += "</td>" text += '<td align="center" bgcolor="%s">' % finalcolor text += "<b><font size=3>=</font></b>" text += "</td>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%d </font></b>" % Elements.Element[ele][ 'Z'] text += "</td>" #name text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>Name</font></b>" text += "</td>" text += '<td align="center" bgcolor="%s">' % finalcolor text += "<b><font size=3>=</font></b>" text += "</td>" text += '<td align="left" bgcolor="%s">' % finalcolor name = Elements.Element[ele]['name'][0].upper( ) + Elements.Element[ele]['name'][1:] text += "<b><font size=3>%s </font></b>" % name text += "</td>" #mass text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>At. Weight</font></b>" text += "</td>" text += '<td align="center" bgcolor="%s">' % finalcolor text += "<b><font size=3>=</font></b>" text += "</td>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.5f </font></b>" % Elements.Element[ele][ 'mass'] text += "</td>" #density text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>Density</font></b>" text += "</td>" text += '<td align="center" bgcolor="%s">' % finalcolor text += "<b><font size=3>=</font></b>" text += "</td>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.5f g/cm3</font></b>" % Elements.Element[ ele]['density'] text += "</td>" text += "</tr>" text += "</table>" # Shell (round) propierties hcolor = 'white' finalcolor = 'white' if Elements.Element[ele]['Z'] > 2: text += "<br><b><font color=blue size=4>Fluorescence Yields (Rounded)</font></b>" text += "<nobr><table><tr>" text += '<td align="left" bgcolor="%s"><b>' % hcolor text += 'Shell' text += "</b></td>" text += '<td align="right" bgcolor="%s"><b>' % hcolor text += 'Yield' text += "</b></td>" text += "</tr>" text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%s </font></b>" % "K" text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.3f </font></b>" % round(omegak, 3) text += "</td>" for i in range(len(omegal)): if omegal[i] > 0.0: text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>L%d </font></b>" % (i + 1) text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.3f </font></b>" % round( omegal[i], 3) text += "</td>" for i in range(len(omegam)): if omegam[i] > 0.0: text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>M%d </font></b>" % (i + 1) text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.3f </font></b>" % round( omegam[i], 3) text += "</td>" text += "</tr>" text += "</table>" # Shell propierties hcolor = 'white' finalcolor = 'white' if Elements.Element[ele]['Z'] > 2: text += "<br><b><font color=blue size=4>Fluorescence Yields</font></b>" text += "<nobr><table><tr>" text += '<td align="left" bgcolor="%s"><b>' % hcolor text += 'Shell' text += "</b></td>" text += '<td align="right" bgcolor="%s"><b>' % hcolor text += 'Yield' text += "</b></td>" text += "</tr>" text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%s </font></b>" % "K" text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.3e </font></b>" % omegak text += "</td>" for i in range(len(omegal)): if omegal[i] > 0.0: text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>L%d </font></b>" % (i + 1) text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.3e </font></b>" % omegal[i] text += "</td>" for i in range(len(omegam)): if omegam[i] > 0.0: text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>M%d </font></b>" % (i + 1) text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.3e </font></b>" % omegam[i] text += "</td>" text += "</tr>" text += "</table>" hcolor = 'white' finalcolor = 'white' f = ['f12', 'f13', 'f23'] ck = [] doit = 0 for item in f: value = Elements.Element[ele]['CosterKronig']['L'][item] if value > 0: doit = 1 ck.append(value) if doit: text += "<br><b><font color=blue size=4>L-Shell Coster-Kronig</font></b>" text += "<nobr><table><tr>" for item in f: text += '<td align="left" bgcolor="%s"><b>' % hcolor text += item text += "</b></td>" text += "</tr>" text += "<tr>" for i in range(len(f)): text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.3f </font></b>" % ck[i] text += "</td>" text += "</tr>" text += "</table>" #M shell fs = [['f12', 'f13', 'f14', 'f15'], ['f23', 'f24', 'f25'], ['f34', 'f35'], ['f45']] doit = 0 for f in fs: for item in f: value = Elements.Element[ele]['CosterKronig']['M'][item] if value > 0: doit = 1 if doit: text += "<br><b><font color=blue size=4>M-Shell Coster-Kronig</font></b>" text += "<nobr><table>" for f in fs: text += "<tr>" for item in f: text += '<td align="left" bgcolor="%s"><b>' % hcolor text += item text += "</b></td>" text += "</tr>" text += "<tr>" for item in f: text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.3f </font></b>" % Elements.Element[ ele]['CosterKronig']['M'][item] text += "</td>" text += "</tr>" text += "</table>" hcolor = 'white' finalcolor = 'white' for rays in Elements.Element[ele]['rays']: if rays == "Ka xrays": continue if rays == "Kb xrays": continue #text+="<center>" text += "<br><b><font color=blue size=4>%s Emission Energies</font></b>" % rays[ 0:-1] #text+="</center>" if 0: for transition in Elements.Element[ele][rays]: text += "<br><b><font size=3>%s energy = %.5f rate = %.5f</font></b>" % ( transition, Elements.Element[ele][transition]['energy'], Elements.Element[ele][transition]['rate']) else: text += "<nobr><table><tr>" text += '<td align="left" bgcolor="%s"><b>' % hcolor text += 'Line' text += "</b></td>" text += '<td align="right" bgcolor="%s"><b>' % hcolor text += 'Energy (keV)' text += "</b></td>" text += '<td align="right" bgcolor="%s"><b>' % hcolor text += 'Rate' text += "</b></td>" text += "</tr>" for transition in Elements.Element[ele][rays]: transitiontext = transition.replace('*', '') text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%s </font></b>" % transitiontext text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.5f</font></b>" % Elements.Element[ ele][transition]['energy'] text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.5f </font></b>" % Elements.Element[ ele][transition]['rate'] text += "</td>" text += "</tr>" text += "</table>" hcolor = 'white' finalcolor = 'white' #text+="<center>" text += "<br><b><font color=blue size=4>%s Binding Energies</font></b>" % "Electron" #text+="</center>" text += "<nobr><table><tr>" text += '<td align="left" bgcolor="%s"><b>' % hcolor text += 'Shell' text += "</b></td>" text += '<td align="right" bgcolor="%s"><b>' % hcolor text += 'Energy (keV)' text += "</b></td>" text += "</tr>" for shell in Elements.ElementShells: if Elements.Element[ele]['binding'][shell] > 0.0: text += "<tr>" text += '<td align="left" bgcolor="%s">' % finalcolor text += "<b><font size=3>%s </font></b>" % shell text += "</td>" text += '<td align="right" bgcolor="%s">' % finalcolor text += "<b><font size=3>%.5f </font></b>" % Elements.Element[ ele]['binding'][shell] text += "</td>" text += "</tr>" text += "</table>" return text
def plot(data, labels=None, cfg=None, xrange=None, yrange=None, normtochan=None, savename='plot.png'): data = np.array(data) #expected dimensions: [N, channels] if len(data.shape) == 1: data = np.reshape((1, data.shape[0])) elif len(data.shape) >= 3: print("Error: expected data dimensions: [N, channels]; ", data.shape) return if cfg is not None: # we're looking for the energy calibration values... from PyMca5.PyMca import ConfigDict config = ConfigDict.ConfigDict() config.read(cfg) cfg = [ config['detector']['zero'], config['detector']['gain'], config['fit']['energy'][0] ] #zero, gain, E_Rayleigh names = [] peaks = list(config['peaks'].keys()) for peak in peaks: for linetype in config['peaks'][peak]: names.append(peak + ' ' + str(linetype)) plt.figure(figsize=(20, 15)) for j in range(0, data.shape[0]): spe = data[j, :] if labels is None: lbl = 'spectrum ' + str(j) else: lbl = labels[j] if normtochan is not None: spe = spe[:] / spe[normtochan] if cfg is None: zero = 0. gain = 1. xtitle = "Channel Number" else: zero = cfg[0] gain = cfg[1] xtitle = "Energy [keV]" # plot the spectrum, Ylog, X-axis converted to Energy (keV) if PyMca cfg provided if xrange is None: xrange = (zero, (spe.shape[0] - 1) * gain + zero) plt.plot(np.linspace(0, spe.shape[0] - 1, num=spe.shape[0]) * gain + zero, spe, label=lbl, linestyle='-') ax = plt.gca() handles, labels = ax.get_legend_handles_labels() plt.yscale('log') plt.xlim(xrange) if yrange is not None: plt.ylim(yrange) plt.legend(handles, labels, loc='best') ax.set_xlabel(xtitle, fontsize=16) ax.set_ylabel("Intensity [counts]", fontsize=16) ax.tick_params(axis='both', which='major', labelsize=14) ax.tick_params(axis='x', which='minor', bottom=True) # add peak annotation if names and cfg provided if cfg is not None: # x axis of plot is in Energy (keV) # determine peak energy values (Rayl energy = cfg[2]) from PyMca5.PyMcaPhysics.xrf import Elements for n in names: if n != 'Rayl' and n != 'Compt': if n.split(" ")[1][0] == 'K': energy = Elements.getxrayenergy( n.split(" ")[0], n.split(" ")[1] + 'L3') #Ka1 elif n.split(" ")[1][0] == 'L': energy = Elements.getxrayenergy( n.split(" ")[0], n.split(" ")[1] + '3M5') #La1 elif n.split(" ")[1][0] == 'M': energy = Elements.getxrayenergy( n.split(" ")[0], n.split(" ")[1] + '5N7') #Ma1 elif n == 'Rayl': energy = cfg[2] else: energy = None # if energy not None, plot label at this energy value if energy is not None: idx = max(np.where(handles[0].get_xdata() <= energy)[-1]) yval = 10**( np.log10(max([hand.get_ydata()[idx] for hand in handles])) * 1.025) # plot the text label X% above this value plt.text(energy, yval, n, horizontalalignment='center', fontsize=14) plt.show() plt.savefig(savename) #, bbox_inches='tight', pad_inches=0) plt.close()
def h5_plot(h5file, channel='channel00', label=None, xrange=None, normtochan=None, yrange=None): # read the h5 file, formatted according to the XMI format # If fit was performed, also read in the PyMCA config file to figure out detector calibration h5file = np.array(h5file) plt.figure(figsize=(20, 15)) for j in range(0, h5file.size): if h5file.size == 1: savename = str(h5file).split('.')[0] + '.png' h5 = str(h5file) else: savename = str(h5file[0]).split('.')[0] + '-' + str( h5file[-1]).split('.')[0].split('/')[-1] + '.png' h5 = str(h5file[j]) fileid = str(h5.split('.')[0].split('/')[-1]) if channel == 'all': chnl = ['channel00', 'channel02'] for i in range(0, 2): spe, names, cfg = gplot_rh5(h5, chnl[i]) if normtochan is not None: spe = spe[:] / spe[normtochan] if cfg is None: zero = 0. gain = 1. xtitle = "Channel Number" else: zero = cfg[0] gain = cfg[1] xtitle = "Energy [keV]" # plot the spectrum, Ylog, X-axis converted to Energy (keV) if PyMca cfg provided plt.plot( np.linspace(0, spe.shape[0] - 1, num=spe.shape[0]) * gain + zero, spe, label=fileid + '_' + str(chnl[i]), linestyle='-') else: spe, names, cfg = gplot_rh5(h5, channel) if normtochan is not None: spe = spe[:] / spe[normtochan] if cfg is None: zero = 0. gain = 1. xtitle = "Channel Number" else: zero = cfg[0] gain = cfg[1] xtitle = "Energy [keV]" # plot the spectrum, Ylog, X-axis converted to Energy (keV) if PyMca cfg provided if xrange is None: xrange = (zero, (spe.shape[0] - 1) * gain + zero) plt.plot( np.linspace(0, spe.shape[0] - 1, num=spe.shape[0]) * gain + zero, spe, label=fileid + '_' + str(channel), linestyle='-') ax = plt.gca() handles, labels = ax.get_legend_handles_labels() plt.yscale('log') plt.xlim(xrange) if yrange is not None: plt.ylim(yrange) plt.legend(handles, labels, loc='best') ax.set_xlabel(xtitle, fontsize=16) ax.set_ylabel("Intensity [counts]", fontsize=16) ax.tick_params(axis='both', which='major', labelsize=14) ax.tick_params(axis='x', which='minor', bottom=True) # add peak annotation if names and cfg provided if cfg is not None and names is not None: # x axis of plot is in Energy (keV) # determine peak energy values (Rayl energy = cfg[2]) from PyMca5.PyMcaPhysics.xrf import Elements for n in names: if n != 'Rayl' and n != 'Compt': if n.split(" ")[1][0] == 'K': energy = Elements.getxrayenergy( n.split(" ")[0], n.split(" ")[1] + 'L3') #Ka1 elif n.split(" ")[1][0] == 'L': energy = Elements.getxrayenergy( n.split(" ")[0], n.split(" ")[1] + '3M5') #La1 elif n.split(" ")[1][0] == 'M': energy = Elements.getxrayenergy( n.split(" ")[0], n.split(" ")[1] + '5N7') #Ma1 elif n == 'Rayl': energy = cfg[2] else: energy = None # if energy not None, plot label at this energy value if energy is not None: idx = max(np.where(handles[0].get_xdata() <= energy)[-1]) yval = 10**( np.log10(max([hand.get_ydata()[idx] for hand in handles])) * 1.025) # plot the text label X% above this value plt.text(energy, yval, n, horizontalalignment='center', fontsize=14) #TODO: Increase fontsizes, add minor tickmarks on x-axis plt.show() plt.savefig(savename) #, bbox_inches='tight', pad_inches=0) plt.close()
def FindXrays(elsym, energy=60.0, minenergy=1.0, maxenergy=35.0, minrate=0.00010): xr = ['K', 'L', 'M'] # chosenxr=[] # chosenxren=[] foundpeaks = [] allpeaksdictlist = [] eltr_quantels = [] for ele in elsym: ElDict = {} PyMEl._updateElementDict(ele, ElDict, energy=energy, minenergy=minenergy, minrate=minrate) xray_en_rate = [[x, ElDict[tr]['energy'], ElDict[tr]['rate']] for x in xr for tr in ElDict['%s xrays' % x] if ElDict[tr]['energy'] < maxenergy] xraytypes = set([xer[0] for xer in xray_en_rate]) totyieldlist = [] eltrlist = [] for xt in xraytypes: totyield = numpy.float32([ v for k, v in PyMEl.Element[ele].iteritems() if k.startswith('omega' + xt.lower()) ]).sum() totyieldlist += [totyield] en_rate = [[xer[1], xer[2]] for xer in xray_en_rate if xer[0] == xt] en_rate = numpy.float32(en_rate) enofmaxrate = en_rate[numpy.argmax(en_rate[:, 1]), 0] eltrlist += [' '.join((ele, xt))] dt = {} dt['el'] = ele dt['tr'] = xt dt['eltr'] = ' '.join((ele, xt)) dt['repen'] = enofmaxrate dt['totyield'] = totyield allpeaksdictlist += [dt] # if len(xraytypes)>1: # tempstr=' and '.join(list(xraytypes)) # print 'XRF ANALYSIS PROBLEM: ', tempstr, ' transitions can be fit but only one will be chosen for', ele if len(xraytypes) == 0: print 'XRF ANALYSIS PROBLEM: no valid transitions could be found for ', ele foundpeaks += [False] else: foundpeaks += [True] eltr_quantels += [ eltrlist[numpy.argmax(numpy.float32(totyieldlist))] ] # xray_en_rate=sorted(xray_en_rate, key=operator.itemgetter(2), reverse=True) # print xray_en_rate # chosenxr+=[' '.join((ele, xray_en_rate[0][0]))] # chosenxren+=[xray_en_rate[0][1]] # return chosenxr, chosenxren, foundpeaks return allpeaksdictlist, eltr_quantels, foundpeaks
def correctNormalizedSpectrum(self, energy0, spectrum): """ """ element = self._configuration['XAS']['element'] material = self._configuration['XAS'].get('material', element) edge = self._configuration['XAS']['edge'] alphaIn, alphaOut = self._configuration['XAS']['angles'] edgeEnergy = Elements.Element[element]['binding'][edge] userEdgeEnergy = self._configuration['XAS'].get('energy', edgeEnergy) energy = numpy.array(energy0, dtype=numpy.float) #PyMca data ar in keV but XAS data are usually in eV if 0.5 * (energy[0] + energy[-1])/edgeEnergy > 100: # if the user did not do stupid things most likely # the energy was given in eV energy *= 0.001 if userEdgeEnergy/edgeEnergy > 100: userEdgeEnergy *= 0.001 # forget about multilayers for the time being # Elements.getMaterialMassFractions(materialList, massFractionsList) massFractions = Elements.getMaterialMassFractions([material], [1.0]) # calculate the total mass attenuation coefficients at the given energies # exciting the given element shell and not exciting it EPDL = Elements.PyMcaEPDL97 totalCrossSection = 0.0 totalCrossSectionBackground = 0.0 for ele in massFractions.keys(): # make sure EPDL97 respects the Elements energies if EPDL.EPDL97_DICT[ele]['original']: EPDL.setElementBindingEnergies(ele, Elements.Element[ele]['binding']) if ele == element: # make sure we respect the user energy if abs(userEdgeEnergy-edgeEnergy) > 0.01: newBinding = Elements.Element[ele]['binding'] newBinding[edge] = userEdgeEnergy try: EPDL.setElementBindingEnergies(ele, newBinding) crossSections = EPDL.getElementCrossSections(ele, energy) EPDL.setElementBindingEnergies(ele, Elements.Element[ele]['binding']) except: EPDL.setElementBindingEnergies(ele, Elements.Element[ele]['binding']) raise else: crossSections = EPDL.getElementCrossSections(ele, energy) else: crossSections = EPDL.getElementCrossSections(ele, energy) total = numpy.array(crossSections['total']) tmpFloat = massFractions[ele] * total totalCrossSection += tmpFloat if ele != element: totalCrossSectionBackground += tmpFloat else: edgeCrossSections = numpy.array(crossSections[edge]) muSampleJump = massFractions[ele] * edgeCrossSections totalCrossSectionBackground += massFractions[ele] *\ (total - edgeCrossSections) # calculate the mass attenuation coefficient of the sample at the fluorescent energy # assume we are detecting the main fluorescence line of the element shell if edge == 'K': rays = Elements.Element[element]["Ka xrays"] elif edge[0] == 'L': rays = Elements.Element[element][edge + " xrays"] elif edge[0] == 'M': rays = [] for transition in Elements.Element[element]['M xrays']: if transition.startswith(edge): rays.append(transition) lineList = [] for label in rays: ene = Elements.Element[element][label]['energy'] rate = Elements.Element[element][label]['rate'] lineList.append([ene, rate, label]) # whithin 50 eV lines considered the same lineList = Elements._filterPeaks(lineList, ethreshold=0.050) # now take the returned line with the highest intensity fluoLine = lineList[0] for line in lineList: if line[1] > fluoLine[1]: fluoLine = line # and calculate the sample total mass attenuation muTotalFluorescence = 0.0 for ele in massFractions.keys(): crossSections = EPDL.getElementCrossSections(ele, fluoLine[0]) muTotalFluorescence += massFractions[ele] * crossSections['total'][0] #define some convenience variables sinIn = numpy.sin(numpy.deg2rad(alphaIn)) sinOut= numpy.sin(numpy.deg2rad(alphaOut)) g = sinIn / sinOut if 1: # thick sample idx = numpy.where(muSampleJump > 0.0)[0][0] muSampleJump[0:idx] = muSampleJump[idx] ALPHA = g * (muTotalFluorescence/muSampleJump) + totalCrossSectionBackground/muSampleJump return (spectrum * ALPHA)/(1 + ALPHA - spectrum) elif 1: # all samples (to be tested) d = thickness * density idx = numpy.where(muSampleJump > 0.0)[0][0] muSampleJump[0:idx] = muSampleJump[idx] ALPHA = g * (muTotalFluorescence/muSampleJump) + totalCrossSectionBackground/muSampleJump thickTarget0 = (spectrum * ALPHA)/(1 + ALPHA - spectrum) # Iterate to find the solution x = spectrum t = (ALPHA + 1) * d * muSampleJump/sinIn if t.max() < 0.001: A = 1 - t else: A = numpy.exp(-t) t = (ALPHA * d * muSampleJump/sinIn) if t.max() < 0.001: B = 1.0 - t else: B = numpy.exp(-t) delta = 10.0 i = 0 while (delta > 1.0e-5) and (i < 30): old = x x = thickTarget0 * (1.0 - A) / \ (1.0 - B * numpy.exp(- x * d * muSampleJump/sinIn)) delta = numpy.abs(x - old).max() i += 1 return x else: thickness = 1.0 density = 1.0e-6 # FORMULA Booth and Bridges ALPHA = g * muTotalFluorescence + totalCrossSection tmpFloat0 = density * thickness * ALPHA / sinIn tmpFloat1 = numpy.exp(-tmpFloat0) BETA = (muSampleJump * tmpFloat0) * tmpFloat1 GAMMA = 1.0 - tmpFloat1 b = GAMMA * ( ALPHA - muSampleJump * spectrum + BETA) discriminant = b*b + 4 * ALPHA * BETA * GAMMA * (spectrum - 1.0) return 1 + (-b + numpy.sqrt(discriminant))/(2 * BETA)