def WDSCrystal(xrt, n=1, R=RolandCircleRadius): """Synatx: WDSCrystal(xrt,n=1,[R=RolandCircleRadius]) Prints a list of the WDS crystals alternatives along with the associated L-value. (Note: xrt may be an element or an XRayTransitionSet (see getTransitionSet(...))""" xrts = [] if isinstance(xrt, epq.XRayTransition): xrts = xrts + [xrt] elif isinstance(xrt, str) or isinstance(xrt, epq.Element): elm = dtsa2.element(xrt) for tr in [epq.XRayTransition.KA1, epq.XRayTransition.LA1, epq.XRayTransition.MA1]: if epq.XRayTransition.exists(elm, tr): xrts = xrts + [epq.XRayTransition(elm, tr)] elif isinstance(xrt, epq.XRayTransitionSet): xrts = xrt.getTransitions() else: print "Invalid argument: %s" % xrt return zippo = True for cry, twoD in TwoDSpacing.iteritems(): for tr in xrts: L = WDS_L(cry, tr, n, R) if (L > 60) and (L < 260): if zippo: print "Crystal\tLine\tL Value" zippo = False print "%s\t%s\t%3.6g" % (cry, tr, L) if zippo: print "None"
def anaMcNiCuKa(spc, det, stdBase, maxCh=1200): props=spc.getProperties() e0 = props.getNumericProperty(epq.SpectrumProperties.BeamEnergy) lt = props.getNumericProperty(epq.SpectrumProperties.LiveTime) pc = props.getNumericProperty(epq.SpectrumProperties.FaradayBegin) wkDst = props.getNumericProperty(epq.SpectrumProperties.WorkingDistance) spc = jmg.cropSpec(spc, end=maxCh) unSpc = jmg.updateCommonSpecProps(spc, det, liveTime=lt, probeCur=pc, e0=e0, wrkDist=wkDst) dt2.display(unSpc) # define the transitions I want to measure tsNiKa = epq.XRayTransitionSet(epq.Element.Ni, epq.XRayTransitionSet.K_FAMILY) tsCuKa = epq.XRayTransitionSet(epq.Element.Cu, epq.XRayTransitionSet.K_FAMILY) trs = [tsNiKa, tsCuKa] relStd = "/%gkV/" % (e0) stdDir = stdBase + relStd niFile = stdDir + "Ni-sim.msa" cuFile = stdDir + "Cu-sim.msa" spc = dt2.wrap(ept.SpectrumFile.open(niFile)[0]) props=spc.getProperties() e0 = props.getNumericProperty(epq.SpectrumProperties.BeamEnergy) lt = props.getNumericProperty(epq.SpectrumProperties.LiveTime) pc = props.getNumericProperty(epq.SpectrumProperties.FaradayBegin) wkDst = props.getNumericWithDefault(epq.SpectrumProperties.WorkingDistance, wkDst) spc = jmg.cropSpec(spc, end=maxCh) niSpc = jmg.updateCommonSpecProps(spc, det, liveTime=lt, probeCur=pc, e0=e0, wrkDist=wkDst) dt2.display(niSpc) spc = dt2.wrap(ept.SpectrumFile.open(cuFile)[0]) props=spc.getProperties() e0 = props.getNumericProperty(epq.SpectrumProperties.BeamEnergy) lt = props.getNumericProperty(epq.SpectrumProperties.LiveTime) pc = props.getNumericProperty(epq.SpectrumProperties.FaradayBegin) wkDst = props.getNumericWithDefault(epq.SpectrumProperties.WorkingDistance, wkDst) spc = jmg.cropSpec(spc, end=maxCh) cuSpc = jmg.updateCommonSpecProps(spc, det, liveTime=lt, probeCur=pc, e0=e0, wrkDist=wkDst) dt2.display(cuSpc) niStd = {"El":dt2.element("Ni"), "Spc":niSpc} cuStd = {"El":dt2.element("Cu"), "Spc":cuSpc} stds = [niStd, cuStd] theKR = jmg.compKRs(unSpc, stds, trs, det, e0) krNiCalc = theKR[0] krCuCalc = theKR[1] return [krNiCalc, krCuCalc]
def minEdge(elm): """Example: minEdge("Ag") Returns the lowest energy edge which is likely to be visible in an EDS detector for the specified element""" elm = dtsa2.element(elm) if elm.getAtomicNumber() >= MinMElement: res = epq.AtomicShell(elm, epq.AtomicShell.MV) elif elm.getAtomicNumber() >= MinLElement: res = epq.AtomicShell(elm, epq.AtomicShell.LIII) else: res = epq.AtomicShell(elm, epq.AtomicShell.K) return res
def ranges(comp, e0, over=1.5): """Example: ranges(createMaterial(),5.0,1.5) Prints a list of edges, over voltages, and ionization ranges (in meters) for the specified material at the specified beam energy in keV (5.0) and required overvoltage (1.5)""" print "Shell\tOver\tRange (m)" comp = dtsa2.material(comp) for elm in comp.getElementSet(): elm = dtsa2.element(elm) sh = maxEdge(elm, e0, over) if sh != None: print "%s\t%g\t%e" % ( sh, e0 / epq.FromSI.keV(sh.getEdgeEnergy()), epq.ElectronRange.KanayaAndOkayama1972.compute( comp, sh, epq.ToSI.keV(e0)) / comp.getDensity()) else: print "%s\tNone\tNone" % elm
def maxEdge(elm, e0, over=1.5): """Example: maxEdge("Ag", 20.0, 1.5) Returns the highest energy edge which is excited with the overvoltage specified (1.5) for the specified beam energy (20.0).""" elm = dtsa2.element(elm) e0 = epq.ToSI.keV(e0) res = None if elm.getAtomicNumber() > MinMElement: sh = epq.AtomicShell.MV if epq.AtomicShell.getEdgeEnergy(elm, sh) * over <= e0: res = epq.AtomicShell(elm, sh) if elm.getAtomicNumber() > MinLElement: sh = epq.AtomicShell.LIII if epq.AtomicShell.getEdgeEnergy(elm, sh) * over <= e0: res = epq.AtomicShell(elm, sh) sh = epq.AtomicShell.K if epq.AtomicShell.getEdgeEnergy(elm, sh) * over <= e0: res = epq.AtomicShell(elm, sh) return res
def buildVectors(stds, path=None, strip=(), det=None): """buildVectors(stds, path=None,strip=()) Construct a set of Schamber-style fast quant vectors stds = { "Fe" : "Fe std", "Cr": "Cr std", "Cd":s101 ... } path = "/home/nicholas/standards" or similar (None -> defaultPath) strip= ("C", "O", ...) a list of elements to strip (must also be in stds)""" procStds = {} strip = [element(elm) for elm in strip] e0 = None for elm, std in stds.iteritems(): if isinstance(std, str): path = (path if path else defaultVecPath) std = readSpectrum("%s/%s" % (path, std)) elif isinstance(std, dt2.ScriptableSpectrum): std = std.wrapped det = (det if det else std.getProperties().detector) procStds[dt2.element(elm)] = std e0 = (e0 if e0 else epq.ToSI.keV(dt2.wrap(std).beamEnergy())) sv = fq.SchamberVectors(det, e0) for elm, std in procStds.iteritems(): sv.addStandard(elm, std, elm in strip) return sv.getVectorSet()
def quantify(rpl, stds, refs={}, preferred=(), elmByDiff=None, elmByStoic=None, assumedStoic={}, mask=None, step=1, visualize=False, zaf=None, withUnc=False): """quantify(rpl,stds,[refs={}],[preferred=()],[elmByDiff=None],[elmByStoic=None],[assumedStoic={}], [mask=None],[zaf=None], [withUnc=False]) Quantify a ripple/raw spectrum object based on the standards, references and other parameters specified. / The arguments are the same as dtsa2.multiQuant. An additional 'mask' argument allows uninteresting pixels / to be ignored (not quantified.) The mask should be an object like a BufferedImage with a getRGB(x,y) method. / The pixel is ignored if mask.getRGB(x,y)==0. The result is written to a RPL/RAW file in FLOAT format. > import javax.imageio.ImageIO as io > mask = io.read(jio.File("c:/image.png")) > zaf = epq.CorrectionAlgorithm.NullCorrection for k-ratios""" oldSt = None try: if (zaf != None) and isinstance(zaf, epq.CorrectionAlgorithm): oldSt = epq.AlgorithmUser.getGlobalStrategy() newSt = epq.AlgorithmUser.getGlobalStrategy() newSt.addAlgorithm(epq.CorrectionAlgorithm, zaf) epq.AlgorithmUser.applyGlobalOverride(newSt) det = rpl.getProperties().getDetector() e0 = rpl.getProperties().getNumericProperty( epq.SpectrumProperties.BeamEnergy) mq = dt2.multiQuant(det, e0, stds, refs, preferred, elmByDiff, elmByStoic, assumedStoic) base = rpl.getProperties().getTextProperty( epq.SpectrumProperties.SourceFile) compRpl = base.replace(".rpl", "_comp.rpl") compRaw = base.replace(".rpl", "_comp.raw") compTxt = base.replace(".rpl", "_comp.txt") status = file(compTxt, "wt") status.write("File:\t%s\n" % base) status.write("Results:\t%s\n" % compRpl) status.write("Detector:\t%s\n" % det) status.write("Beam energy\t%g keV\n" % e0) status.write("Standards\n") i = 0 elms = [] # Ensures the plane order is correct if det.getChannelCount() != rpl.getChannelCount(): print "ERROR: The number of channels in %s (%d) doesn't match the number of channels in the RPL file (%d)." % ( det, det.getChannelCount(), rpl.getChannelCount()) return for elm, std in stds.iteritems(): if std.getChannelCount() != rpl.getChannelCount(): print "ERROR: The number of channels in %s (%d) doesn't match the number of channels in the RPL file (%d)." % ( std, std.getChannelCount(), rpl.getChannelCount()) return status.write("\t%d\t%s\t%s\n" % (i, elm, std)) elms.append(dt2.element(elm)) i = i + 1 if len(refs) > 0: status.write("References\n") for xrt, ref in refs.iteritems(): if ref.getChannelCount() != rpl.getChannelCount(): print "ERROR: The number of channels in %s (%d) doesn't match the number of channels in the RPL file (%d)." % ( ref, ref.getChannelCount(), rpl.getChannelCount()) status.write("\t%s\t%s\n" % (xrt, ref)) if len(preferred) > 0: status.write("Preferred transitions\n") for xrt in preferred: status.write("\t%s for %s\n" % (xrt, xrt.getElement())) if elmByDiff: status.write("Element by difference: %s\n" % elmByDiff) if elmByStoic: status.write("Element by Stoiciometry: %s\n" % elmByStoic) status.write("Element\tValence\n") for elm, stoic in assumedStoic.iteritems(): status.write("\t%s\t%g\n" % (elm, stoic)) comps = ept.RippleFile((rpl.getColumns() + step - 1) / step, (rpl.getRows() + step - 1) / step, len(stds) + 1, ept.RippleFile.FLOAT, 8, ept.RippleFile.DONT_CARE_ENDIAN, compRpl, compRaw) uncert = None if withUnc: uncRaw = base.replace(".rpl", "_unc.raw") uncRpl = base.replace(".rpl", "_unc.rpl") uncert = ept.RippleFile((rpl.getColumns() + step - 1) / step, (rpl.getRows() + step - 1) / step, len(stds) + 1, ept.RippleFile.FLOAT, 8, ept.RippleFile.DONT_CARE_ENDIAN, uncRpl, uncRaw) dumpIt = False if dumpIt: dumpRpl = base.replace(".rpl", "_dump.rpl") dumpRaw = base.replace(".rpl", "_dump.raw") dump = ept.RippleFile((rpl.getColumns() + step - 1) / step, (rpl.getRows() + step - 1) / step, rpl.getChannelCount(), ept.RippleFile.UNSIGNED, 4, ept.RippleFile.DONT_CARE_ENDIAN, dumpRpl, dumpRaw) rpl.setSpan(step, step) for r in xrange(0, rpl.getRows(), step): if dt2.isTerminated(): break dt2.StdOut.append(".") dt2.StdOut.flush() for c in xrange(0, rpl.getColumns(), step): if dt2.isTerminated(): break if visualize: dt2.clearSpectra() dt2.display(rpl) comps.setPosition(c / step, r / step) if (mask == None) or ((mask.getRGB(c, r) & 0xFFFFFF) > 0): try: rpl.setPosition(c, r) rs = epq.SpectrumUtils.copy(rpl) if dumpIt: # print "%d\t%d\t%d\t%d" % (c, r, c / step, r / step) dump.setPosition(c / step, r / step) dump.write(epq.SpectrumUtils.toIntArray(rs)) res = mq.compute(rs) comp = res.getComposition() if visualize: rpl.getProperties().setCompositionProperty( epq.SpectrumProperties. MicroanalyticalComposition, comp) dt2.annotComposition() tmp, unc = [], [] sU = 0.0 for elm in elms: tmp.append(comp.weightFraction(elm, True)) u = comp.weightFractionU(elm, True).uncertainty() unc.append(u) sU = sU + u * u tmp.append(comp.sumWeightFraction()) unc.append(jl.Math.sqrt(sU)) if dumpIt: print tmp comps.write(tmp) if uncert: uncert.write(unc) except (epq.EPQException, Exception, jl.Exception), e: msg = "row = %d, col = %d failed: %s" % (r, c, e) print msg status.write(msg + "\n") for elm, std in stds.iteritems(): comps.write(0.0) if uncert: uncert.write(unc) if visualize: dt2.setAnnotation("row = %d, col = %d failed." % (r, c)) else: for elm, std in stds.iteritems(): comps.write(0.0) if uncert: uncert.write(unc) comps.write(1.0) if uncert: uncert.write(1.0) comps.close() if uncert: uncert.close() if dumpIt: dump.close() status.close()
def simLineInMatrix(lin, linMat, blk, blkMat, nmLinWid, umBlock, nPts, trs, outDir, hdr, det, e0, lt, pc, withPoisson=True, nTraj=100, sf=True, bf=True, iDigits=5, bVerbose=False, xtraParams={}): """simLineInMatrix(lin, linMat, blk, blkMat, nmLinWid, umBlock, nPts, trs, outDir, hdr, det, e0, lt, pc, withPoisson=True, nTraj=nTraj, sf=True, bf=True, iDigits=5, bVerbose=False, xtraParams={}) Simulate a line of width `nmLinWid' nm at the center of a block of `umBlock' microns. The line is of material `lin' with a name `linMat'. The block is of material `blk' with a name `blkMat'. We analyze an list `trs' of transitions, writing the K-ratios to a .csv file with a header `hdr'. We use the detector `det', voltage `e0' (kV) and live time `lt' sec and probe current `pc' nA. This will compute the standard spectra, compute the spectra for nPts+1 from -nPts/2 ... 0 ...nPts/2 times the block size. It will then compute the K-ratios for each spectrum and write them to a file `name' in outDir with a header `hdr' that matches the transition order. """ # order is order of trs.. sc = 1.0e-6 # scale from microns to meters for positions lX = [] # an array for postions lKlin = [] # an array for the K-ratio of the line lKblk = [ ] # an array for the K-ratio of the block. Title correspond to hdr string # start clean dt2.DataManager.clearSpectrumList() # create the standards linStd = simulateBulkStandard(lin, linMat, det, e0, lt, pc, withPoisson=True, nTraj=nTraj, sf=True, bf=True, xtraParams={}) dt2.display(linStd) blkStd = simulateBulkStandard(blk, blkMat, det, e0, lt, pc, withPoisson=True, nTraj=nTraj, sf=True, bf=True, xtraParams={}) dt2.display(blkStd) lStd = {"El": dt2.element(linMat), "Spc": linStd} bStd = {"El": dt2.element(blkMat), "Spc": blkStd} stds = [lStd, bStd] # note: put the transitions in this order iCount = 0 for x in range(-nPts / 2, (nPts / 2) + 1, 1): xv = sc * x * umBlock / nPts lX.append(round(x * umBlock / nPts, iDigits)) monte = nm.MonteCarloSS() monte.setBeamEnergy(epq.ToSI.keV(e0)) # use a 1 nm probe beam = nm.GaussianBeam(1.0e-9) monte.setElectronGun(beam) beam.setCenter([xv, 0.0, -0.05]) # createBlock(double[] dims, double[] point, double phi, double theta, double psi) # createBlock - Create a block of: # dimensions specified in dims, # centered at point, # then rotated by the euler angles phi, theta, psi. block = nm.MultiPlaneShape.createBlock( [umBlock * 1.0e-6, umBlock * 1.0e-6, umBlock * 1.0e-6], [0.0, 0.0, 0.5 * umBlock * 1.0e-6], 0.0, 0.0, 0.0) matrix = monte.addSubRegion(monte.getChamber(), blk, block) monte.addSubRegion( matrix, lin, nm.MultiPlaneShape.createBlock( [1.0e-9 * nmLinWid, umBlock * 1.0e-6, umBlock * 1.0e-6], [0.0, 0.0, 0.5 * umBlock * 1.0e-6], 0.0, 0.0, 0.0)) det.reset() # Add event listeners to model characteristic radiation chXR = nm3.CharacteristicXRayGeneration3.create(monte) xrel = nm3.XRayTransport3.create(monte, det, chXR) brXR = nm3.BremsstrahlungXRayGeneration3.create(monte) brem = nm3.XRayTransport3.create(monte, det, brXR) fxg3 = nm3.FluorescenceXRayGeneration3.create(monte, chXR) chSF = nm3.XRayTransport3.create(monte, det, fxg3) brSF = nm3.XRayTransport3.create( monte, det, nm3.FluorescenceXRayGeneration3.create(monte, brXR)) # here is where we run the simulation monte.runMultipleTrajectories(nTraj) spec = det.getSpectrum((lt * pc * 1.0e-9) / (nTraj * epq.PhysicalConstants.ElectronCharge)) props = spec.getProperties() props.setNumericProperty(epq.SpectrumProperties.LiveTime, lt) props.setNumericProperty(epq.SpectrumProperties.FaradayBegin, pc) props.setNumericProperty(epq.SpectrumProperties.FaradayEnd, pc) props.setNumericProperty(epq.SpectrumProperties.BeamEnergy, e0) spcName = "x = %.3f um" % x epq.SpectrumUtils.rename(spec, spcName) spec = epq.SpectrumUtils.addNoiseToSpectrum(spec, 1.0) # display(spec) a = jmg.compKRs(spec, stds, trs, det, e0) iCount += 1 print(iCount) lKlin.append(round(a[0], iDigits)) lKblk.append(round(a[1], iDigits)) basFile = "%gnm-%s-in-%gum-%s-%gkV-%g-Traj.csv" % ( nmLinWid, linMat, umBlock, blkMat, e0, nTraj) strOutFile = outDir + "/" + basFile f = open(strOutFile, 'w') strLine = hdr + '\n' f.write(strLine) for i in range(iCount): strLine = "%.5f" % lX[i] + "," strLine = strLine + "%.5f" % lKlin[i] + "," strLine = strLine + "%.5f" % lKblk[i] + "\n" f.write(strLine) f.close()
def simLineInMatrixLimScan(lin, linMat, blk, blkMat, nmLinWid, umBlock, nmScan, nPts, trs, outDir, hdr, det, e0, lt, pc, withPoisson=True, nTraj=100, sf=True, bf=True, iDigits=5, bVerbose=False, xtraParams={}): """simLineInMatrixLimScan(lin, linMat, blk, blkMat, nmLinWid, umBlock, nmScan, nPts, trs, outDir, hdr, det, e0, lt, pc, withPoisson=True, nTraj=nTraj, sf=True, bf=True, iDigits=5, bVerbose=False, xtraParams={}) Simulate a line of width `nmLinWid' nm at the center of a block of `umBlock' microns. The line is of material `lin' with a name `linMat'. The block is of material `blk' with a name `blkMat'. We step a total distance of nmScan across the center of the line. We analyze an list `trs' of transitions, writing the K-ratios to a .csv file with a header `hdr'. We use the detector `det', voltage `e0' (kV) and live time `lt' sec and probe current `pc' nA. This will compute the standard spectra, compute the spectra the scanned region. It will then compute the K-ratios for each spectrum and write them to a file `name' in outDir with a header `hdr' that matches the transition order. """ # order is order of trs.. sc = 1.0e-6 # scale from microns to meters for positions dose = lt * pc lX = [] # an array for postions lKlin = [] # an array for the K-ratio of the line lKblk = [ ] # an array for the K-ratio of the block. Title correspond to hdr string umLine = nmLinWid * 1.0e-3 # start clean dt2.DataManager.clearSpectrumList() # create the standards linStd = simulateBulkStandard(lin, linMat, det, e0, lt, pc, withPoisson=withPoisson, nTraj=nTraj, sf=sf, bf=bf, xtraParams={}) dt2.display(linStd) blkStd = simulateBulkStandard(blk, blkMat, det, e0, lt, pc, withPoisson=withPoisson, nTraj=nTraj, sf=sf, bf=sf, xtraParams={}) dt2.display(blkStd) lStd = {"El": dt2.element(linMat), "Spc": linStd} bStd = {"El": dt2.element(blkMat), "Spc": blkStd} stds = [lStd, bStd] # note: put the transitions in this order iCount = 0 for x in range(-nPts / 2, (nPts / 2) + 1, 1): xPosNm = x * nmScan / nPts lX.append(round(xPosNm, iDigits)) xtraParams = {} xtraParams.update( mc3.configureXRayAccumulators(trs, charAccum=sf, charFluorAccum=sf, bremFluorAccum=bf)) xtraParams.update(mc3.configureOutput(outDir)) xtraParams.update(mc3.configureBeam(xPosNm * 1.0e-09, 0, -0.099, 1.0)) spec = mc3.embeddedRectangle(lin, [umLine * sc, umBlock * sc, umBlock * sc], blk, 0, det, e0, withPoisson=withPoisson, nTraj=nTraj, dose=dose, sf=sf, bf=bf, xtraParams=xtraParams) props = spec.getProperties() props.setNumericProperty(epq.SpectrumProperties.LiveTime, lt) props.setNumericProperty(epq.SpectrumProperties.FaradayBegin, pc) props.setNumericProperty(epq.SpectrumProperties.FaradayEnd, pc) props.setNumericProperty(epq.SpectrumProperties.BeamEnergy, e0) spcName = "x = %.3f um" % x epq.SpectrumUtils.rename(spec, spcName) spec = epq.SpectrumUtils.addNoiseToSpectrum(spec, 1.0) # display(spec) a = jmg.compKRs(spec, stds, trs, det, e0) iCount += 1 print(iCount, xPosNm) lKlin.append(round(a[0], iDigits)) lKblk.append(round(a[1], iDigits)) basFile = "%gnm-%s-in-%gum-%s-%gkV-%g-Traj.csv" % ( nmLinWid, linMat, umBlock, blkMat, e0, nTraj) strOutFile = outDir + "/" + basFile f = open(strOutFile, 'w') strLine = hdr + '\n' f.write(strLine) for i in range(iCount): strLine = "%.3f" % lX[i] + "," strLine = strLine + "%.5f" % lKlin[i] + "," strLine = strLine + "%.5f" % lKblk[i] + "\n" f.write(strLine) f.close()
def zaf(comp, det, e0, nTraj=defaultNumTraj, stds={}): """zaf(comp, det, e0, nTraj = 1000, stds=None) Example: mc3.zaf(material("Al2O3",1),d2,10.0,stds={ "Al":"Al", "O":"MgO" }) The Monte Carlo equivalent of dtsa2.zaf(comp,det,e0,stds) in the base DTSA-II scripting package. \ Tabulates the ZAF corrections as computed from Monte Carlo simulations of the generated and emitted x-ray \ intensities normalized relative to the specified standards (or if no standards are specified relative to \ pure elements)""" def doMonte(cc): monte = nm.MonteCarloSS() monte.setBeamEnergy(epq.ToSI.keV(e0)) monte.addSubRegion(chamber, cc, nm.MultiPlaneShape.createSubstrate([0.0, 0.0, -1.0], origin)) # Add event listeners to model characteristic radiation chXR = nm3.CharacteristicXRayGeneration3.create(monte) chTr = nm3.XRayTransport3.create(monte, det, chXR) xrel = nm3.XRayAccumulator3(xrts, "Characteristic") chTr.addXRayListener(xrel) fxg3 = nm3.FluorescenceXRayGeneration3.create(monte, chXR) chSFTr = nm3.XRayTransport3.create(monte, det, fxg3) chSF = nm3.XRayAccumulator3(xrts, "Secondary") chSFTr.addXRayListener(chSF) det.reset() monte.runMultipleTrajectories(nTraj) return (xrel, chSF) comp = dtsa2.material(comp, 1.0) print u"Material\t%s" % comp.descriptiveString(0) print u"Detector\t%s" % det print u"Algorithm\t%s" % "Monte Carlo (Gen3)" print u"MAC\t%s" % epq.AlgorithmUser.getDefaultMAC().getName() print u"E0\t%0.1f keV" % e0 print u"Take-off\t%g%s" % (jl.Math.toDegrees(epq.SpectrumUtils.getTakeOffAngle(det.getProperties())), epq.SpectrumProperties.TakeOffAngle.getUnits()) elms = comp.getElementSet() allStds = {} for elm, std in stds.iteritems(): allStds[dtsa2.element(elm)] = dtsa2.material(std, 1.0) for elm in elms: if not allStds.has_key(elm): allStds[elm] = dtsa2.material(elm.toAbbrev(), 1.0) origin = epq.SpectrumUtils.getSamplePosition(det.getProperties()) xrts = dtsa2.majorTransitions(comp, e0, thresh=0.8) xrel, chSF = {}, {} for elm in elms: xrel[elm], chSF[elm] = doMonte(allStds[elm]) # Run unknown xrelu, chSFu = doMonte(dtsa2.material(comp, 1.0)) print u"\nIUPAC\tSeigbahn\tStandard\tEnergy\t ZAF\t Z\t A\t F\tk-ratio" for elm in elms: xrels = xrel[elm] chSFs = chSF[elm] cu = comp.weightFraction(elm, False) cs = allStds[elm].weightFraction(elm, False) for xrt in xrts: if xrt.getElement().equals(elm) and (xrels.getEmitted(xrt) > 0.0) and (xrelu.getEmitted(xrt) > 0.0): try: # print "%g\t%g\t%g\t%g" % (xrelu.getGenerated(xrt), xrelu.getEmitted(xrt),xrels.getGenerated(xrt), xrels.getEmitted(xrt) ) a = (xrelu.getEmitted(xrt) * xrels.getGenerated(xrt)) / (xrelu.getGenerated(xrt) * xrels.getEmitted(xrt)) z = (cs * xrelu.getGenerated(xrt)) / (cu * xrels.getGenerated(xrt)) f = (1.0 + chSFu.getEmitted(xrt) / xrelu.getEmitted(xrt)) / (1.0 + chSFs.getEmitted(xrt) / xrels.getEmitted(xrt)) k = (xrelu.getEmitted(xrt) / xrels.getEmitted(xrt)) * f eTr = epq.FromSI.keV(xrt.getEnergy()) print u"%s\t%s\t%s\t%2.4f\t%1.4f\t%1.4f\t%1.4f\t%1.4f\t%1.4f" % (xrt, xrt.getSiegbahnName(), allStds[elm], eTr, z * a * f, z, a, f, k) except: print u"%s - %s" % (elm, xrt)
def quantify(rpl, stds, refs={}, preferred=(), elmByDiff=None, elmByStoic=None, assumedStoic={}, mask=None, step=1, visualize=False, zaf=None, withUnc=False): """quantify(rpl,stds,[refs={}],[preferred=()],[elmByDiff=None],[elmByStoic=None],[assumedStoic={}], [mask=None],[zaf=None], [withUnc=False]) Quantify a ripple/raw spectrum object based on the standards, references and other parameters specified. / The arguments are the same as dtsa2.multiQuant. An additional 'mask' argument allows uninteresting pixels / to be ignored (not quantified.) The mask should be an object like a BufferedImage with a getRGB(x,y) method. / The pixel is ignored if mask.getRGB(x,y)==0. The result is written to a RPL/RAW file in FLOAT format. > import javax.imageio.ImageIO as io > mask = io.read(jio.File("c:/image.png")) > zaf = epq.CorrectionAlgorithm.NullCorrection for k-ratios""" oldSt = None try: if (zaf != None) and isinstance(zaf, epq.CorrectionAlgorithm): oldSt = epq.AlgorithmUser.getGlobalStrategy() newSt = epq.AlgorithmUser.getGlobalStrategy() newSt.addAlgorithm(epq.CorrectionAlgorithm, zaf) epq.AlgorithmUser.applyGlobalOverride(newSt) det = rpl.getProperties().getDetector() e0 = rpl.getProperties().getNumericProperty(epq.SpectrumProperties.BeamEnergy) mq = dt2.multiQuant(det, e0, stds, refs, preferred, elmByDiff, elmByStoic, assumedStoic) base = rpl.getProperties().getTextProperty(epq.SpectrumProperties.SourceFile) compRpl = base.replace(".rpl", "_comp.rpl") compRaw = base.replace(".rpl", "_comp.raw") compTxt = base.replace(".rpl", "_comp.txt") status = file(compTxt, "wt") status.write("File:\t%s\n" % base) status.write("Results:\t%s\n" % compRpl) status.write("Detector:\t%s\n" % det) status.write("Beam energy\t%g keV\n" % e0) status.write("Standards\n") i = 0; elms = [] # Ensures the plane order is correct if det.getChannelCount() != rpl.getChannelCount(): print "ERROR: The number of channels in %s (%d) doesn't match the number of channels in the RPL file (%d)." % (det, det.getChannelCount(), rpl.getChannelCount()) return for elm, std in stds.iteritems(): if std.getChannelCount() != rpl.getChannelCount(): print "ERROR: The number of channels in %s (%d) doesn't match the number of channels in the RPL file (%d)." % (std, std.getChannelCount(), rpl.getChannelCount()) return status.write("\t%d\t%s\t%s\n" % (i, elm, std)) elms.append(dt2.element(elm)) i = i + 1 if len(refs) > 0: status.write("References\n") for xrt, ref in refs.iteritems(): if ref.getChannelCount() != rpl.getChannelCount(): print "ERROR: The number of channels in %s (%d) doesn't match the number of channels in the RPL file (%d)." % (ref, ref.getChannelCount(), rpl.getChannelCount()) status.write("\t%s\t%s\n" % (xrt, ref)) if len(preferred) > 0: status.write("Preferred transitions\n") for xrt in preferred: status.write("\t%s for %s\n" % (xrt, xrt.getElement())) if elmByDiff: status.write("Element by difference: %s\n" % elmByDiff) if elmByStoic: status.write("Element by Stoiciometry: %s\n" % elmByStoic) status.write("Element\tValence\n") for elm, stoic in assumedStoic.iteritems(): status.write("\t%s\t%g\n" % (elm, stoic)) comps = ept.RippleFile((rpl.getColumns() + step - 1) / step, (rpl.getRows() + step - 1) / step, len(stds) + 1, ept.RippleFile.FLOAT, 8, ept.RippleFile.DONT_CARE_ENDIAN, compRpl, compRaw) uncert = None if withUnc: uncRaw = base.replace(".rpl", "_unc.raw") uncRpl = base.replace(".rpl", "_unc.rpl") uncert = ept.RippleFile((rpl.getColumns() + step - 1) / step, (rpl.getRows() + step - 1) / step, len(stds) + 1, ept.RippleFile.FLOAT, 8, ept.RippleFile.DONT_CARE_ENDIAN, uncRpl, uncRaw) dumpIt = False if dumpIt: dumpRpl = base.replace(".rpl", "_dump.rpl") dumpRaw = base.replace(".rpl", "_dump.raw") dump = ept.RippleFile((rpl.getColumns() + step - 1) / step, (rpl.getRows() + step - 1) / step, rpl.getChannelCount(), ept.RippleFile.UNSIGNED, 4, ept.RippleFile.DONT_CARE_ENDIAN, dumpRpl, dumpRaw) rpl.setSpan(step, step) for r in xrange(0, rpl.getRows(), step): if dt2.isTerminated(): break dt2.StdOut.append(".") dt2.StdOut.flush() for c in xrange(0, rpl.getColumns(), step): if dt2.isTerminated(): break if visualize: dt2.clearSpectra() dt2.display(rpl) comps.setPosition(c / step, r / step) if (mask == None) or ((mask.getRGB(c, r) & 0xFFFFFF) > 0): try: rpl.setPosition(c, r) rs = epq.SpectrumUtils.copy(rpl) if dumpIt: # print "%d\t%d\t%d\t%d" % (c, r, c / step, r / step) dump.setPosition(c / step, r / step) dump.write(epq.SpectrumUtils.toIntArray(rs)) res = mq.compute(rs) comp = res.getComposition() if visualize: rpl.getProperties().setCompositionProperty(epq.SpectrumProperties.MicroanalyticalComposition, comp) dt2.annotComposition() tmp, unc = [], [] sU = 0.0 for elm in elms: tmp.append(comp.weightFraction(elm, True)) u = comp.weightFractionU(elm, True).uncertainty() unc.append(u) sU = sU + u*u tmp.append(comp.sumWeightFraction()) unc.append(jl.Math.sqrt(sU)) if dumpIt: print tmp comps.write(tmp) if uncert: uncert.write(unc) except (epq.EPQException, Exception, jl.Exception), e: msg = "row = %d, col = %d failed: %s" % (r, c, e) print msg status.write(msg + "\n") for elm, std in stds.iteritems(): comps.write(0.0) if uncert: uncert.write(unc) if visualize: dt2.setAnnotation("row = %d, col = %d failed." % (r, c)) else: for elm, std in stds.iteritems(): comps.write(0.0) if uncert: uncert.write(unc) comps.write(1.0) if uncert: uncert.write(1.0) comps.close() if uncert: uncert.close() if dumpIt: dump.close() status.close()
def simLineInMatrixLimScan(lin, linMat, blk, blkMat, nmLinWid, umBlock,nmScan, nPts, trs, outDir, hdr, det, e0, lt, pc, withPoisson=True, nTraj=100, sf=True, bf=True, iDigits=5, bVerbose=False, xtraParams={}): """simLineInMatrixLimScan(lin, linMat, blk, blkMat, nmLinWid, umBlock, nmScan, nPts, trs, outDir, hdr, det, e0, lt, pc, withPoisson=True, nTraj=nTraj, sf=True, bf=True, iDigits=5, bVerbose=False, xtraParams={}) Simulate a line of width `nmLinWid' nm at the center of a block of `umBlock' microns. The line is of material `lin' with a name `linMat'. The block is of material `blk' with a name `blkMat'. We step a total distance of nmScan across the center of the line. We analyze an list `trs' of transitions, writing the K-ratios to a .csv file with a header `hdr'. We use the detector `det', voltage `e0' (kV) and live time `lt' sec and probe current `pc' nA. This will compute the standard spectra, compute the spectra the scanned region. It will then compute the K-ratios for each spectrum and write them to a file `name' in outDir with a header `hdr' that matches the transition order. """ # order is order of trs.. sc = 1.0e-6 # scale from microns to meters for positions dose = lt*pc lX = [] # an array for postions lKlin = [] # an array for the K-ratio of the line lKblk = [] # an array for the K-ratio of the block. Title correspond to hdr string umLine = nmLinWid * 1.0e-3 # start clean dt2.DataManager.clearSpectrumList() # create the standards linStd = simulateBulkStandard(lin, linMat, det, e0, lt, pc, withPoisson=withPoisson, nTraj=nTraj, sf=sf, bf=bf, xtraParams={}) dt2.display(linStd) blkStd = simulateBulkStandard(blk, blkMat, det, e0, lt, pc, withPoisson=withPoisson, nTraj=nTraj, sf=sf, bf=sf, xtraParams={}) dt2.display(blkStd) lStd = {"El":dt2.element(linMat), "Spc":linStd} bStd = {"El":dt2.element(blkMat), "Spc":blkStd} stds = [lStd, bStd] # note: put the transitions in this order iCount = 0 for x in range(-nPts/2, (nPts/2)+1, 1): xPosNm = x * nmScan / nPts lX.append(round(xPosNm, iDigits)) xtraParams={} xtraParams.update(mc3.configureXRayAccumulators(trs, charAccum=sf, charFluorAccum=sf, bremFluorAccum=bf)) xtraParams.update(mc3.configureOutput(outDir)) xtraParams.update(mc3.configureBeam(xPosNm*1.0e-09, 0, -0.099, 1.0)) spec = mc3.embeddedRectangle(lin, [umLine*sc, umBlock*sc, umBlock*sc], blk, 0, det, e0, withPoisson=withPoisson, nTraj=nTraj, dose=dose, sf=sf, bf=bf, xtraParams=xtraParams) props = spec.getProperties() props.setNumericProperty(epq.SpectrumProperties.LiveTime, lt) props.setNumericProperty(epq.SpectrumProperties.FaradayBegin, pc) props.setNumericProperty(epq.SpectrumProperties.FaradayEnd, pc) props.setNumericProperty(epq.SpectrumProperties.BeamEnergy, e0) spcName = "x = %.3f um" % x epq.SpectrumUtils.rename(spec, spcName) spec = epq.SpectrumUtils.addNoiseToSpectrum(spec, 1.0) # display(spec) a = jmg.compKRs(spec, stds, trs, det, e0) iCount += 1 print(iCount, xPosNm) lKlin.append(round(a[0], iDigits)) lKblk.append(round(a[1], iDigits)) basFile ="%gnm-%s-in-%gum-%s-%gkV-%g-Traj.csv" % (nmLinWid, linMat, umBlock, blkMat, e0, nTraj) strOutFile = outDir + "/" + basFile f=open(strOutFile, 'w') strLine = hdr + '\n' f.write(strLine) for i in range(iCount): strLine = "%.3f" % lX[i] + "," strLine = strLine + "%.5f" % lKlin[i] + "," strLine = strLine + "%.5f" % lKblk[i] + "\n" f.write(strLine) f.close()
def simLineInMatrix(lin, linMat, blk, blkMat, nmLinWid, umBlock, nPts, trs, outDir, hdr, det, e0, lt, pc, withPoisson=True, nTraj=100, sf=True, bf=True, iDigits=5, bVerbose=False, xtraParams={}): """simLineInMatrix(lin, linMat, blk, blkMat, nmLinWid, umBlock, nPts, trs, outDir, hdr, det, e0, lt, pc, withPoisson=True, nTraj=nTraj, sf=True, bf=True, iDigits=5, bVerbose=False, xtraParams={}) Simulate a line of width `nmLinWid' nm at the center of a block of `umBlock' microns. The line is of material `lin' with a name `linMat'. The block is of material `blk' with a name `blkMat'. We analyze an list `trs' of transitions, writing the K-ratios to a .csv file with a header `hdr'. We use the detector `det', voltage `e0' (kV) and live time `lt' sec and probe current `pc' nA. This will compute the standard spectra, compute the spectra for nPts+1 from -nPts/2 ... 0 ...nPts/2 times the block size. It will then compute the K-ratios for each spectrum and write them to a file `name' in outDir with a header `hdr' that matches the transition order. """ # order is order of trs.. sc = 1.0e-6 # scale from microns to meters for positions lX = [] # an array for postions lKlin = [] # an array for the K-ratio of the line lKblk = [] # an array for the K-ratio of the block. Title correspond to hdr string # start clean dt2.DataManager.clearSpectrumList() # create the standards linStd = simulateBulkStandard(lin, linMat, det, e0, lt, pc, withPoisson=True, nTraj=nTraj, sf=True, bf=True, xtraParams={}) dt2.display(linStd) blkStd = simulateBulkStandard(blk, blkMat, det, e0, lt, pc, withPoisson=True, nTraj=nTraj, sf=True, bf=True, xtraParams={}) dt2.display(blkStd) lStd = {"El":dt2.element(linMat), "Spc":linStd} bStd = {"El":dt2.element(blkMat), "Spc":blkStd} stds = [lStd, bStd] # note: put the transitions in this order iCount = 0 for x in range(-nPts/2, (nPts/2)+1, 1): xv = sc*x*umBlock/nPts lX.append(round(x*umBlock/nPts, iDigits)) monte=nm.MonteCarloSS() monte.setBeamEnergy(epq.ToSI.keV(e0)) # use a 1 nm probe beam=nm.GaussianBeam(1.0e-9) monte.setElectronGun(beam) beam.setCenter([xv, 0.0,-0.05]) # createBlock(double[] dims, double[] point, double phi, double theta, double psi) # createBlock - Create a block of: # dimensions specified in dims, # centered at point, # then rotated by the euler angles phi, theta, psi. block = nm.MultiPlaneShape.createBlock([umBlock*1.0e-6, umBlock*1.0e-6, umBlock*1.0e-6],[0.0,0.0, 0.5*umBlock*1.0e-6],0.0,0.0,0.0) matrix = monte.addSubRegion(monte.getChamber(), blk, block) monte.addSubRegion(matrix, lin, nm.MultiPlaneShape.createBlock([1.0e-9*nmLinWid, umBlock*1.0e-6, umBlock*1.0e-6],[0.0, 0.0, 0.5*umBlock*1.0e-6],0.0,0.0,0.0)) det.reset() # Add event listeners to model characteristic radiation chXR = nm3.CharacteristicXRayGeneration3.create(monte) xrel = nm3.XRayTransport3.create(monte, det, chXR) brXR = nm3.BremsstrahlungXRayGeneration3.create(monte) brem = nm3.XRayTransport3.create(monte, det, brXR) fxg3 = nm3.FluorescenceXRayGeneration3.create(monte, chXR) chSF = nm3.XRayTransport3.create(monte, det, fxg3) brSF = nm3.XRayTransport3.create(monte, det, nm3.FluorescenceXRayGeneration3.create(monte, brXR)) # here is where we run the simulation monte.runMultipleTrajectories(nTraj) spec = det.getSpectrum((lt*pc*1.0e-9) / (nTraj * epq.PhysicalConstants.ElectronCharge)) props = spec.getProperties() props.setNumericProperty(epq.SpectrumProperties.LiveTime, lt) props.setNumericProperty(epq.SpectrumProperties.FaradayBegin, pc) props.setNumericProperty(epq.SpectrumProperties.FaradayEnd, pc) props.setNumericProperty(epq.SpectrumProperties.BeamEnergy, e0) spcName = "x = %.3f um" % x epq.SpectrumUtils.rename(spec, spcName) spec = epq.SpectrumUtils.addNoiseToSpectrum(spec, 1.0) # display(spec) a = jmg.compKRs(spec, stds, trs, det, e0) iCount += 1 print(iCount) lKlin.append(round(a[0], iDigits)) lKblk.append(round(a[1], iDigits)) basFile ="%gnm-%s-in-%gum-%s-%gkV-%g-Traj.csv" % (nmLinWid, linMat, umBlock, blkMat, e0, nTraj) strOutFile = outDir + "/" + basFile f=open(strOutFile, 'w') strLine = hdr + '\n' f.write(strLine) for i in range(iCount): strLine = "%.5f" % lX[i] + "," strLine = strLine + "%.5f" % lKlin[i] + "," strLine = strLine + "%.5f" % lKblk[i] + "\n" f.write(strLine) f.close()