Scripting example #3

In this example, we will generate an x-ray spectrum image. To make life a little interesting we will generate spectra for a particle on a carbon matrix as we raster the beam over the sample. The resulting data will consist of a 64 x 64 x 2048 data cube which will be saved in RAW format such as read by the program LISPIX. Using LISPIX we will reduce the resulting data cube down to a set of elemental images.

# Example #3
import gov.nist.microanalysis.EPQLibrary as epq
import gov.nist.microanalysis.NISTMonte as nm
import gov.nist.microanalysis.EPQTools as et
import java.util as jutil
import java.io as jio
import java.nio.charset as cs

dest = DefaultOutput
dest.mkdirs()

nTraj=10
characteristic=1
brem=1
res=et.RippleFile(64, 64, 2048, et.RippleFile.FLOAT, 4, et.RippleFile.BIG_ENDIAN, dest.toString()+"\K411.rpl",dest.toString()+"\K411.raw")
for x in range(-32,32):
  for y in range(-32,32):
    print "%d, %d" % (x,y)
    #create an instance of the model
    monte=nm.MonteCarloSS()
    monte.setBeamEnergy(epq.ToSI.keV(25.0))
    beam=nm.MonteCarloSS.GaussianBeam(monte,1.0e-9)
    beam.setCenter([0.6e-6*x/32.0,0.6e-6*y/32.0,-0.05])
    monte.setElectronGun(beam)
    # create the sample
    k411=epq.MaterialFactory.createMaterial("K411")
    part=nm.Sphere([0.0,0.0,-0.5e-6],0.5e-6)
    monte.addSubRegion(monte.getChamber(),k411,part)
    c=epq.MaterialFactory.createPureElement(epq.Element.C)
    block=nm.MultiPlaneShape.createBlock([20.0e-6,20.0e-6,20.0e-6],[0.0,0.0,10.0e-6],0.0,0.0,0.0)
    monte.addSubRegion(monte.getChamber(),c,block)
    if 0:
      # Add a VRML detector
      fos=jio.FileOutputStream("%s/K411 (%d,%d).wrl" % (dest,x,y))
      tw=jio.OutputStreamWriter(fos,cs.Charset.forName("UTF-8"))
      vrml = nm.TrajectoryVRML(monte,tw)
      vrml.setMaxTrajectories(20)
      vrml.setTrajectoryWidth(1.0e-8)
      vrml.setDisplayBackscatter(1)
      vrml.addView("Gun",[0.0,0.0,-5.0e-5],[0.0,0.0,0.0])
      vrml.addView("X-Axis",[5.0e-5,0.0,0.0,0.0],[0.0,0.0,0.0])
      vrml.addView("Y-Axis",[0.0,5.0e-5,0.0,0.0],[0.0,0.0,0.0])
      vrml.renderSample()
      monte.addActionListener(vrml)
      monte.runMultipleTrajectories(20)
      tw.flush()
      fos.close()
    if 1:
      # add a detector (to collect a spectrum)
      det = epq.EDSDetector(2048,10.0,130.0)
      det.setGain(1.0e-8/epq.PhysicalConstants.ElectronCharge)
      detPos=monte.computeDetectorPosition(40.0*3.1415/180.0,0.0)
      # add an x-ray event listener
      if characteristic:
        xrel=nm.XRayEventListener(monte,detPos);
        allLines = jutil.HashSet()
        ass = monte.getAtomicShellSet()
        for a in ass:
          allLines.addAll(epq.XRayTransition.createByDestinationShell(a))
          xrel.setTransitions(allLines);
          monte.addActionListener(xrel)
          xrel.addActionListener(det);
        if brem:
          brel = nm.BremsstrahlungEventListener(monte,detPos);
          monte.addActionListener(brel);
          brel.addActionListener(det);
        monte.runMultipleTrajectories(nTraj)
        res.seek(x+32,y+32)
        res.write(epq.SpectrumUtils.toDoubleArray(det))

Text 1:The Jython code for generating an x-ray map on a 1 µm particle of K411 glass.

Particle image

Illustration 1: A VRML image showing a 1 µm K411 particle on a carbon substrate with 20 electron trajectories at 25 keV.

Raster progression

Illustration 2: A series of VRML images showing the beam crossing the particle in a series of equally spaced steps.

Derived spectra

Illustration 4: A pair of spectra derived using LISPIX from the 64 x 64 x 2048 data cube - the sum spectrum and the max-pixel spectrum.

Particle map

Illustration 5: Elemental maps formed using LISPIX by summing over ROI regions for each of the specified elements.