예제 #1
0
def simSonoraSpc(tAl2O3, e0, det, wkDst=5, lt=100, pc=1, nTraj=1000, xtraParams={}):
    """simSonoraSpc(tAl2O3, e0, det, wkDst=5, lt=100, pc=1, nTraj=1000, xtraParams={})
    Simulate a spectrum from tAl2O3 nm of Al2O3 on Al recoreed at
    e0 kV using the DTSA detector det and a wkDst mm working distance for
    lt sec with a probe current of pc nA. Compute nTraj trajectories."""
    tAl = 100 # um
    al2o3 = dt2.material("Al2O3",density=3.95)
    al  = dt2.material("Al", density=2.70)
    lAl2O3 = [al2o3, tAl2O3*1.0e-9]
    lAl = [al, tAl*1.0e-6]
    lay = [lAl2O3, lAl]
    sNam = "%g-nm-Al2O3-on-Al-%g-kV" % (tAl2O3, e0)
    spc = dt2.wrap(mc3.multiFilm(lay, det, e0, True, nTraj, lt*pc, True, True, xtraParams))
    props=spc.getProperties()
    props.setTextProperty(epq.SpectrumProperties.SpectrumDisplayName, sNam)
    props.setNumericProperty(epq.SpectrumProperties.LiveTime, lt)
    props.setNumericProperty(epq.SpectrumProperties.FaradayBegin, pc)
    props.setNumericProperty(epq.SpectrumProperties.BeamEnergy, e0)
    props.setNumericProperty(epq.SpectrumProperties.WorkingDistance, wkDst)
    return(spc)
예제 #2
0
def suggestTransitions(mat, e0=20.0):
   """suggestTransitions(mat, e0=20.0)
   Suggest a list of transitions for the specified material."""
   mat = dtsa2.material(mat)
   xrts = ("%s K-L3", "%s K-M3", "%s L3-M5", "%s L2-N4", "%s M5-N7", "%s M4-N6")   
   res = []
   for elm in mat.getElementSet():
      for xrt in xrts:
         tr = dtsa2.transition(xrt % elm.toAbbrev())
         if tr.exists() and (tr.getEnergy() < 0.95 * epq.ToSI.keV(e0)) and (tr.getEnergy() > epq.ToSI.keV(0.2)):
            res.append(tr)
   return res
예제 #3
0
def simulate(mat, det, e0=20.0, dose=defaultDose, withPoisson=True, nTraj=defaultNumTraj, sf=defaultCharFluor, bf=defaultBremFluor, xtraParams=defaultXtraParams):
   """simulate(mat,det,[e0=20.0],[withPoisson=True],[nTraj=defaultNumTraj],[dose=defaultDose],[sf=defaultCharFluor],[bf=defaultBremFluor],[xtraParams=defaultXtraParams])
   Simulate a bulk spectrum for the material mat on the detector det at beam energy e0 (in keV).  If \
sf then simulate characteristic secondary fluorescence. If bf then simulate bremsstrahlung secondary \
fluorescence. nTraj specifies the number of electron trajectories. dose is in nA*sec."""
   mat = dtsa2.material(mat)
   if not isinstance(mat, epq.Material):
      print u"Please provide a material with a density - %s" % mat
   tmp = u"MC simulation of bulk %s at %0.1f keV%s%s" % (mat, e0, (" + CSF" if sf else ""), (" + BSF" if bf else ""))
   print tmp
   res = base(det, e0, withPoisson, nTraj, dose, sf, bf, tmp, buildBulk, { "Material" : mat }, xtraParams)
   res.getProperties().setCompositionProperty(epq.SpectrumProperties.StandardComposition, mat)
   return res
예제 #4
0
def simNiCuPetSpc(tNi, tCu, e0, det, wkDst=17, lt=100, pc=1, nTraj=1000):
  """simNiCuPetSpc(tNi, tCu, e0, det, wkDst=17, lt=100, pc=1, nTraj=1000)
  Simulate a spectrum from tNi nm of Ni on tCu nm of Cu on PET recoreded at
  e0 kV using the DTSA detector det and a wkDst mm working distance for
  lt sec with a probe current of pc nA. Compute nTraj trajectories."""
  tPET = 76 # um
  pet = dt2.material("C10H8O4",density=1.37)
  cu  = dt2.material("Cu", density=8.96)
  ni  = dt2.material("Ni", density=8.90)
  lNi   = [ni,  tNi*1.0e-9]
  lCu   = [cu,  tCu*1.0e-9]
  lPET  = [pet, tPET*1.0e-6]
  lay   = [lNi, lCu, lPET]
  sNam  = "%g-nm-Ni-%g-nm-Cu-on-PET-%g-kV" % (tNi, tCu, e0)
  spc = dt2.wrap(mc3.multiFilm(lay, det, e0, True, nTraj, lt*pc, True, True))
  props=spc.getProperties()
  props.setTextProperty(epq.SpectrumProperties.SpectrumDisplayName, sNam)
  props.setNumericProperty(epq.SpectrumProperties.LiveTime, lt)
  props.setNumericProperty(epq.SpectrumProperties.FaradayBegin, pc)
  props.setNumericProperty(epq.SpectrumProperties.BeamEnergy, e0)
  props.setNumericProperty(epq.SpectrumProperties.WorkingDistance, wkDst)
  return(spc)
예제 #5
0
def addMeasurement(spec, mat):
    """addMeasurement(spec, mat)
   Add a QC entry based on the specified spectrum collected from the named material.  /
   The spectrum must define the probe current and detector properties."""
    comp = d2.material("__QC__[%s]" % mat)
    if not comp:
        comp = d2.material(mat)
    if not comp:
        raise "Please specify a known material."
    comp.setName(mat)
    det = spec.getProperties().getDetector()
    if not det:
        raise "Please specify a detector in the spectrum properties."
    det = d2.Database.getEarliestCalibrated(det)
    beamE = spec.getProperties().getNumericWithDefault(
        epq.SpectrumProperties.BeamEnergy, 0.0)
    if beamE == 0.0:
        raise "Please specify the beam energy in the spectrum properties."
    qcp = d2.Database.getQCProject(det, comp, beamE)
    mode = d2.Datab
    data = epq.SpectrumFitter7.performQC(det, comp, spec, None)
    d2.Database.addQC(qcp, spec, data)
    print "%s added to %s" % (spec, d2.Database.describeQCProject(qcp))
예제 #6
0
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
예제 #7
0
def suggestTransitionSets(mat, e0=20.0):
   """suggestTransitions(mat, e0=20.0)
   Suggest a list of XRayTransitionSet objects for the specified material."""
   mat = dtsa2.material(mat)
   fams = ("Ka", "Kb", "La", "Lb", "Ma", "Mb")   
   res = []
   for elm in mat.getElementSet():
      for fam in fams:
         xrts = dtsa2.getTransitionSet(elm, fam)
         removeMe = epq.XRayTransitionSet()
         if (xrts.size() > 0):
            for xrt in xrts:
               ee = epq.FromSI.keV(xrt.getEnergy())
               if (ee < 0.2) or (ee > 0.95 * e0):
                  removeMe.add(xrt)
            if removeMe.size() > 0:
               xrts.removeAll(removeMe)
            if xrts.size() > 0:
               res.append(xrts)
   return res
예제 #8
0
def stemCell(h2oThickness,
             objMat,
             objDiameter,
             objDepth,
             e0,
             beamOffset=0.0,
             detectorDistance=0.008,
             detectorRadius=0.02,
             detRingCount=100,
             nTraj=10000):
    """stemCell(h2oThickness, objMat, objDiameter, objDepth, e0, [beamOffset=0.0], [detectorDistance=0.008], [detectorRadius=0.02], [detRingCount=100], [nTraj=10000]):
	Model scattering from a spherical object embedded in a suspended water film.
	Example: 
		> import dtsa2.stemCell as sc
		> sc.stemCell(1.0e-6, material("Au",10.0), 2.0e-7, 4.0e-7, 100.0,nTraj=1000)"""
    monte = nm.MonteCarloSS()
    monte.setBeamEnergy(epq.ToSI.keV(e0))
    beam = nm.GaussianBeam(1.0e-10)
    beam.setCenter((beamOffset, 0.0, -0.01))
    monte.setElectronGun(beam)
    h2o = d2.material("H2O", 1.0)
    h2oThickness = max(h2oThickness, objDiameter)
    objDepth = max(0.5 * objDiameter,
                   min(h2oThickness - 0.5 * objDiameter, objDepth))
    h2oSr = monte.addSubRegion(
        monte.getChamber(), h2o,
        nm.MultiPlaneShape.createFilm((0.0, 0.0, -1.0), (0.0, 0.0, 0.0),
                                      h2oThickness))
    monte.addSubRegion(h2oSr, objMat,
                       nm.Sphere((0.0, 0.0, objDepth), 0.5 * objDiameter))
    ann = nm.AnnularDetector(detectorRadius, detRingCount,
                             (0.0, 0.0, detectorDistance), (0.0, 0.0, -1.0))
    monte.addActionListener(ann)
    monte.runMultipleTrajectories(nTraj)
    header = "Parameters:\nWater thickness\t%g nm\nSphere material\t%s\nSphere diameter\t%g nm\nSphere center depth\t%g nm\nBeam offset\t%g nm\nDetector distance\t%g mm\nDetector radius\t%g mm\nE0\t%g keV" % (
        1.0e9 * h2oThickness, objMat.descriptiveString(False),
        1.0e9 * objDiameter, 1.0e9 * objDepth, 1.0e9 * beamOffset,
        1.0e3 * detectorDistance, 1.0e3 * detectorRadius, e0)
    print header
    return (header, ann)
예제 #9
0
def simCarbonCoatedStd(mat, det, e0, nTraj, lt=100, pc=1.0, tc=20.0):
    """simCarbonCoatedStd(mat, det, e0, nTraj, lt=100, pc=1.0, tc=20.0)

	Use mc3 multilayer simulation to simulate a C-ctd standard specimen

	Parameters
	----------
	mat - a dtsa material.
		Note the material must have an associated density. It should have a useful name.
	det - a dtsa detector
		Here is where we get the detector properties and calibration
	e0 - float
		The accelerating voltage in kV
	nTraj - integer
		The number of trajectories to run
	lt - integer (100)
		The live time (sec)
	pc - float (1.0)
		The probe current in nA
	tc - float (20.0)
		C thickness in nm


	Returns
	-------
	sim - DTSA scriptable spectrum 
		The simulated standard spectrum
	
	Example
	-------
	import dtsa2.jmMC3 as jm3
	det = findDetector("Si(Li)")
	mgo = material("MgO", density=3.58)
	a = jm3.simCarbonCoatedStd(mgo, det, 20.0, 100, 100, 1.0, 20.0)
	a.display()

	"""
    dose = pc * lt  # na-sec"
    c = dt2.material("C", density=2.1)
    layers = [[c, tc * 1.0e-9], [mat, 50.0e-6]]
    xrts = []

    trs = mc3.suggestTransitions(c, e0)
    for tr in trs:
        xrts.append(tr)

    trs = mc3.suggestTransitions(mat, e0)
    for tr in trs:
        xrts.append(tr)

    xtraParams = {}
    xtraParams.update(mc3.configureXRayAccumulators(xrts, True, True, True))

    sim = mc3.multiFilm(layers,
                        det,
                        e0,
                        withPoisson=True,
                        nTraj=nTraj,
                        dose=dose,
                        sf=True,
                        bf=True,
                        xtraParams=xtraParams)
    sName = "%g-nm-C-on-%s-%g-kV-%g-Traj" % (tc, mat, e0, nTraj)
    sim.rename(sName)
    sim.setAsStandard(mat)
    return sim
예제 #10
0
def simCtdOxOnSi(det, e0, nTraj, lt=100, pc=1.0, tox=10.0, tc=20.0):
    """
	simCtdOxOnSi(det, e0, nTraj, lt=100, pc=1.0, tox = 10.0, tc=20.0)

	Use mc3 multilayer simulation to simulate a C-ctd silicon specimen
	with a native oxide layer.

	det - a dtsa detector
		Here is where we get the detector properties and calibration
	e0 - float
		The accelerating voltage in kV
	nTraj - integer
		The number of trajectories to run
	lt - integer (100)
		The live time (sec)
	pc - float (1.0)
		The probe current in nA
	tox - float (10.0)
		The thickness of the native oxide in nm
	tc - float (20.0)
		C thickness in nm


	Returns
	-------
	sim - DTSA scriptable spectrum 
		The simulated spectrum
	
	Example
	-------
	import dtsa2.jmMC3 as jm3
	det = findDetector("Si(Li)")
	a = jm3.simCtdOxOnSi(det, 3.0, 100, 100, 1.0, 10.0, 20.0)
	a.display()

	"""
    c = dt2.material("C", density=2.1)
    si = dt2.material("Si", density=2.329)
    sio2 = dt2.material("SiO2", density=2.65)

    dose = pc * lt  # na-sec"

    layers = [[c, tc * 1.0e-9], [sio2, tox * 1.0e-9], [si, 50.0e-6]]
    xrts = []

    trs = mc3.suggestTransitions(c, e0)
    for tr in trs:
        xrts.append(tr)

    trs = mc3.suggestTransitions(sio2, e0)
    for tr in trs:
        xrts.append(tr)

    xtraParams = {}
    xtraParams.update(mc3.configureXRayAccumulators(xrts, True, True, True))

    sim = mc3.multiFilm(layers,
                        det,
                        e0,
                        withPoisson=True,
                        nTraj=nTraj,
                        dose=dose,
                        sf=True,
                        bf=True,
                        xtraParams=xtraParams)
    sName = "%g-nm-C-on-%g-nm-SiO2-on-Si-%g-kV-%g-Traj" % (tc, tox, e0, nTraj)
    sim.rename(sName)
    return sim
예제 #11
0
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)
예제 #12
0
def createGas(comp, pascal):
    """createGas(comp, pascal)
    Create a gas from a composition at the specified pressure in Pascal at 300 K.
    Ex: createGas("H2O", 0.1)"""
    return epq.Gas(dtsa2.material(comp), pascal, 300.0)
예제 #13
0
def backscatterCoefficient(mat, e0=20.0):
	"""backscatterCoefficient(mat, e0=20.0)
	Computes eta, the backscatter coefficient, for the specified material (element) and beam energy keV."""
	return epq.BackscatterCoefficient.Heinrich81.compute(dtsa2.material(mat),epq.ToSI.keV(e0))
예제 #14
0
def backscatterFraction(mat, e0=20.0):
	"""backscatterFraction(mat)
	Computes the backscatter fraction for an element or composition"""
	mat=dtsa2.material(mat)
	return epq.BackscatterCoefficient.Heinrich81.compute(mat,epq.ToSI.keV(e0))
예제 #15
0
def simCarbonCoatedStd(mat, det, e0, nTraj, lt=100, pc=1.0, tc=20.0):
    """simCarbonCoatedStd(mat, det, e0, nTraj, lt=100, pc=1.0, tc=20.0)

    Use mc3 multilayer simulation to simulate a C-ctd standard specimen

    Parameters
    ----------
    mat - a dtsa material.
        Note the material must have an associated density. It should have a useful name.
    det - a dtsa detector
        Here is where we get the detector properties and calibration
    e0 - float
        The accelerating voltage in kV
    nTraj - integer
        The number of trajectories to run
    lt - integer (100)
        The live time (sec)
    pc - float (1.0)
        The probe current in nA
    tc - float (20.0)
        C thickness in nm


    Returns
    -------
    sim - DTSA scriptable spectrum 
        The simulated standard spectrum
    
    Example
    -------
    import dtsa2.jmMC3 as jm3
    det = findDetector("Oxford p4 05eV 2K")
    mgo = material("MgO", density=3.58)
    a = jm3.simCarbonCoatedStd(mgo, det, 20.0, 100, 100, 1.0, 20.0)
    a.display()

    """
    dose = pc * lt  # na-sec"
    c = dt2.material("C", density=2.1)
    layers = [ [  c, tc*1.0e-9],
               [mat, 50.0e-6]
             ]
    xrts = []

    trs = mc3.suggestTransitions(c, e0)
    for tr in trs:
       xrts.append(tr)

    trs = mc3.suggestTransitions(mat, e0)
    for tr in trs:
        xrts.append(tr)

    xtraParams={}
    xtraParams.update(mc3.configureXRayAccumulators(xrts,True, True, True))

    sim = mc3.multiFilm(layers, det, e0, withPoisson=True, nTraj=nTraj,
                        dose=dose, sf=True, bf=True, xtraParams=xtraParams)
    sName = "%g-nm-C-on-%s-%g-kV-%g-Traj" % (tc, mat, e0, nTraj)
    sim.rename(sName)
    sim.setAsStandard(mat)
    return sim
예제 #16
0
def simCtdOxOnSi(det, e0, nTraj, lt=100, pc=1.0, tox = 10.0, tc=20.0):
    """
    simCtdOxOnSi(det, e0, nTraj, lt=100, pc=1.0, tox = 10.0, tc=20.0)

    Use mc3 multilayer simulation to simulate a C-ctd silicon specimen
    with a native oxide layer.

    det - a dtsa detector
        Here is where we get the detector properties and calibration
    e0 - float
        The accelerating voltage in kV
    nTraj - integer
        The number of trajectories to run
    lt - integer (100)
        The live time (sec)
    pc - float (1.0)
        The probe current in nA
    tox - float (10.0)
        The thickness of the native oxide in nm
    tc - float (20.0)
        C thickness in nm


    Returns
    -------
    sim - DTSA scriptable spectrum 
        The simulated spectrum
    
    Example
    -------
    import dtsa2.jmMC3 as jm3
    det = findDetector("Oxford p4 05eV 2K")
    a = jm3.simCtdOxOnSi(det, 3.0, 100, 100, 1.0, 10.0, 20.0)
    a.display()

    """
    c    = dt2.material("C", density=2.1)
    si   = dt2.material("Si", density=2.329)
    sio2 = dt2.material("SiO2", density=2.65)

    dose = pc * lt  # na-sec"

    layers = [ [   c, tc*1.0e-9],
               [sio2, tox*1.0e-9],
               [si, 50.0e-6] ]
    xrts = []

    trs = mc3.suggestTransitions(c, e0)
    for tr in trs:
       xrts.append(tr)

    trs = mc3.suggestTransitions(sio2, e0)
    for tr in trs:
        xrts.append(tr)

    xtraParams={}
    xtraParams.update(mc3.configureXRayAccumulators(xrts,True, True, True))

    sim = mc3.multiFilm(layers, det, e0, withPoisson=True, nTraj=nTraj,
                        dose=dose, sf=True, bf=True, xtraParams=xtraParams)
    sName = "%g-nm-C-on-%g-nm-SiO2-on-Si-%g-kV-%g-Traj" % (tc, tox, e0, nTraj)
    sim.rename(sName)
    return sim