Spectrum
Working with Spectrum objects
The Spectrum type represents a single spectrum with associated properties. The channel data is indexed like a Vector. The property data is indexed using Symbol objects. A set of spectrum properties are defined in the library and the user can create additional ones.
In addition to the Vector-like properties, the Spectrum associates energy bins with each channel. The energy bins are continuous, non-overlapping and monotonic. Functions like energy(...) maps channel index to energies and channel(...) to make energies to channel index.
NeXLSpectrum.Spectrum — TypeSpectrum{T<:Real} <: AbstractVector{T}
Spectrum(energy::EnergyScale, data::Vector{<:Real}, props::Dict{Symbol,Any})Construct a structure to hold spectrum data (energy scale, counts and metadata).
See NeXLSpectrum.EnergyScale or NeXLSpectrum.LinearEnergyScale
Example:
julia> spec = Spectrum(LinearEnergyScale(0.0,10.0),
collect(1:1024),
Dict{Symbol,Any}(:BeamEnergy=>10.0e3, :LiveTime=>30.0))
** 1024.0
*********
*****************
************************
*******************************
**************************************
*********************************************
****************************************************
***********************************************************
******************************************************************
*************************************************************************
******************************************************************************** 10.0 keV
Spectrum[3062][10.0 keV, Unknown, 525000.0 counts]Spectrum implements indexing using various different mechanisms. If spec is a Spectrum then
spec[123] # will return the number of counts in channel 123
spec[123:222] # will return a Vector of counts from channel 123:222
spec[134.] # will return the number of counts in the channel at energy 134.0 eV
spec[134.0:270.0] # will return a Vector of counts for channels with energies between 134.0 eV and 270.0 eV
spec[:Comment] # will return the property named :CommentMetadata is identified by a symbol. These Symbols are used within NeXLSpectrum.
:BeamEnergy # In eV
:Elevation # In radians
:TakeOffAngle # In radians (Detector position)
:Azimuthal # In radians (Detector position)
:WorkingDistance # In cm
:LiveTime # In seconds
:RealTime # In seconds
:ProbeCurrent # In nano-amps
:Name # A string
:Owner # A string
:StagePosition # A Dict{Symbol,Real} with entries :X, :Y, :Z, :R, :T, B: in cm and degrees
:Comment # A string
:Composition # A Material (known composition, not measured)
:Elements # A collection of elements in the material
:ReferenceROIS # A collection of reference ROIs (as Vector{ReferenceROI})
:Detector # A Detector like a BasicEDS or another EDSDetector
:Filename # Source filename
:Coating # A Film or Film[] (eg. 10 nm of C|Au etc.)
:AcquisitionTime # Date and time of acquisition (DateTime struct)
:Signature # Dict{Element,Real} with the "particle signature"Less common items:
:ImageMag # Magnification (assuming a 3.5" image) of the first image
:ImageZoom # Additional zoom for second image in a two image TIFF
:Operator # Analyst in ASPEX TIFF files
:Image1, :Image2 ... # Images associated with the spectrum
:BrukerThroughtput # Nominal throughtput setting on a Bruker detector
:DetectorSerialNumber # EDS detector serial number
:DetectorModel # Vendor model name
:DetectorThickness # Thickness of detector active area
:DeadLayerThickness # Thickness of Si dead layer on the entrance surface of the detector
:Window # Window construction details
:DetectorSolidAngle # Collection solid angle of the X-ray detector
:ChamberPressure # Vacuum presure in the sample chamber
:ChamberAtmosphere # Nominally the composition of the residual gas in the chamberXRF related items:
:BeamEnergy # Accelarating voltage within X-ray tube (eV)
:XRFTubeAnode # Element from which the X-ray tube is constructed
:ProbeCurrent # Electron current in the X-ray tube
:XRFTubeIncidentAngle # Incident angle of electron beam in tube
:XRFTubeTakeOffAngle # Take-off angle from tube
:XRFExcitationAngle # Angle of incidence of the X-ray beam on the sample
:XRFDetectionAngle # Angle of the detector relative to the sample
:XRFExcitationPathLength # Distance from X-ray source to sample
:XRFDetectionPathLength # Distance from the sample to the X-ray detector
:XRFSampleTilt # Additional tilt of the sample
:XRFTubeWindow # Construction of the tube windowNot all spectra will define all properties. Algorithms can define the NeXLCore.minproperties(ty::Type) method to specify which properties are required by an algorithm of ty::Type. Then hasminrequired and requiredbutmissing methods will determine whether a Spectrum or Dict{Symbol,Any} is suitable for an algorithm.
Acccessing Properties
Most properties are accessed using spec[:Symbol] notation. Some combined or special properties have special methods.
NeXLSpectrum.dose — Functiondose(spec::Spectrum, def=missing)
dose(spec::Spectrum)The probe dose in nano-amp seconds
NeXLCore.elms — Methodelms(spec::Spectrum, withcoating = false, def=missing)Returns a list of the elements associated with this spectrum. withcoating determines whether the coating elements are also added.
Displaying Spectrum Data
NeXLUncertainties.asa — FunctionNeXLUncertainties.asa(::Type{DataFrame}, spec::Spectrum; properties::Bool = false)Converts the spectrum energy and counts data into a DataFrame.
NeXLUncertainties.asa(::Type{DataFrame}, spec::AbstractVector{Spectrum})::DataFrameReturns a DataFrame that summarizes the list of spectra.
NeXLUncertainties.asa(::Type{DataFrame}, spec::AbstractDict{Element, Spectrum})::DataFrameReturns a DataFrame that summarizes a dictionary of standard spectra.
NeXLUncertainties.asa(::Type{DataFrame}, ffrs::AbstractVector{<:FitResult}; charOnly = true, withUnc = false, pivot = false)Return generic FitResult as a DataFrame.
NeXLUncertainties.asa(::Type{DataFrame}, ffr::FilterFitResult)::DataFrameTabulate details about each region-of-interest in the 'FilterFitResult' in a 'DataFrame'.
Base.keys — FunctionBase.keys(spec::Spectrum)Return the defined properties as a set of Symbols.
Base.haskey — FunctionBase.haskey(spec::Spectrum, sym::Symbol)Is the specified key defined?
Gadfly.plot — Functionplot(
specs::Union{Spectrum...,AbstractVector{Spectrum{<:Real}}};
klms=[],
edges=[],
escapes=[],
coincidences=[],
autoklms = false,
xmin=0.0,
xmax=missing,
norm=:None,
yscale=1.05,
ytransform = identity,
style=NeXLSpectrumStyle,
palette=NeXLCore.NeXLPalette
)::PlotRequired:
specs::AbstractVector{Spectrum};Named:
klms = [ Element &| CharXRay ]
edges = [ Element &| AtomicSubShell ]
escapes = [ CharXRay ],
coincidences = [ CharXRay ]
autoklms = false # Add KLMs based on elements in spectra
xmin = 0.0 # Min energy (eV)
xmax = missing # Max energy (eV) (defaults to max(:BeamEnergy))
norm = NoScaling() | ScaleDoseWidth() | ScaleDose() | ScaleSum() | ScaleROISum() | ScalePeak() | (<: SpectrumScaling)()
yscale = 1.05 # Fraction of max intensity for ymax over [max(lld,xmin):xmax]
ytransform = identity | log10 | sqrt | ??? # How to transform the counts data before plotting
style=NeXLSpectrumStyle (or another Gadfly.style)
palette = NeXLCore.NeXLPalette | NeXLCore.NeXLColorblind | Colorant[ ... ] # Colors for spectra...
customlayers = Gadfly.Layer[] # Allows additional plot layers to be addedPlot a multiple spectra on a single plot using Gadfly.
Gadfly.plot(
ffr::FilterFitResult,
roi::Union{Missing,UnitRange{Int}} = missing;
palette = NeXLCore.NeXLPalette,
style = NeXLSpectrumStyle, xmax=missing)Plot the spectrum, residual and k-ratios using Gadfly.
Gadfly.plot(fr::FilteredReference)Plot a filtered reference spectrum.
Energy Scale Functions
These functions handle mapping channel index to energies and vice versa.
NeXLCore.energy — FunctionNeXLCore.energy(ch::Integer, sc::EnergyScale)
NeXLCore.energy(ch::Int, spec::Spectrum)
NeXLCore.energy(ch::Int, det::EDSDetector)Returns the energy (in eV) for the low energy side of the bin representing the ch-th channel.
Example:
les = LinearEnergyScale(3.0, 10.1)
energy(101,lsc) == 10.1*101 + 3.0
energy(101,lsc) - energy(100,lsc) == 10.1
pes = PolyEnergyScale([ 3.0, 10.1, 0.001])
energy(101,pes) == 3.0 + 10.0*101 + 0.001*101^2NeXLSpectrum.channel — Functionchannel(eV::AbstractFloat, sc::EnergyScale)
channel(eV::Float64, spec::Spectrum)
channel(eV::Float64, det::EDSDetector)
Returns the integer index of the channel for the specified energy X-ray (in eV).NeXLSpectrum.rangeofenergies — Functionrangeofenergies(spec::Spectrum, ch)Returns the low and high energy extremes for the channels ch.
NeXLSpectrum.channelwidth — Functionchannelwidth(ch::Int, spec::Spectrum)::Float64Returns the width of the ch channel in eV.
NeXLSpectrum.energyscale — Functionenergyscale(es::EnergyScale, channels)
energyscale(det::EDSDetector)Computes the energy associated with a range of channel indexes and returns it as an Array.
energyscale(spec::Spectrum)Returns an array with the bin-by-bin energies
Extracting the Counts Data
The channel data in a Spectrum object spec can be get/set using standard Array indexing techniques.
> spec[123]
> spec[123:345]
> spec[1234.0] # Channel containing energy 1234.0 eV
> spec[123] = 99Alternatively, the counts(...) method can be used.
NeXLSpectrum.counts — Functioncounts(spec::Spectrum, numType::Type{T}, applyLLD=false)::Vector{T} where {T<:Number}
counts(spec::Spectrum, channels::UnitRange{Int}, numType::Type{T}, applyLLD=false)::Vector{T} where {T<:Number}Creates a copy of the spectrum counts data as the specified Number type. If the spectrum has a :Detector property then the detector's lld (low-level discriminator) and applyLLD=true then the lld is applied to the result by setting all channels less-than-or-equal to det.lld to zero.
counts(...) can apply the :LLD property to zero counts below a specified channel.
NeXLSpectrum.lld — Functionlld(det::EDSDetector)Low level detection limit in channels. Channels at or below this value will be zeroed when the lld is applied.
lld(spec::Spectrum)Gets the low-level discriminator associated with this spectrum if there is one.
Defining Detectors
Build a detector to match the data in a Spectrum.
NeXLSpectrum.simpleEDS — FunctionsimpleEDS(chCount::Integer, width::Float64, offset::Float64, fwhmatmnka::Float64, lld::Int = channel(150.0 eV))Construct simple model of an EDS detector.
simpleEDS(spec::Spectrum, fwhmatmnka::Float64)Build a EDSDetector object for this spectrum with the specified FWHM at Mn Kα.
NeXLSpectrum.matching — Functionmatching(spec::Spectrum, resMnKa::Float64, lld::Int=1)::BasicEDSBuild an EDSDetector to match the channel count and energy scale in this spectrum.
Statistical Sub-Sampling
NeXLSpectrum.subdivide — Functionsubdivide(spec::Spectrum, n::Int)::Vector{Spectrum}Splits the event data in one spectrum into n spectra by assigning each event to a pseudo-random choice of one of the n result spectra. Produces n spectra that act as though the original spectrum was collected in n time intervals of LiveTime/n. This is quite slow because it needs to call rand() for each count in the spectrum (not just each channel).
NeXLSpectrum.subsample — Functionsubsample(spec::Spectrum, frac::Float64)Subsample the counts data in a spectrum according to a statistically valid algorithm. Returns spec if frac>=1.0.
Processing Channel Data
NeXLSpectrum.kratio — Functionkratio(unk::Spectrum, std::Spectrum, back1::UnitRange{Int}, peak::UnitRange{Int}, back2::UnitRange{Int})::UncertainValue
kratio(unk::Spectrum, std::Spectrum, back1::StepRangeLen{Float64}, peak::StepRangeLen{Float64}, back2::StepRangeLen{Float64})::UncertainValueThe k-ratio of unk relative to std corrected for dose. Requires that unk and std have the properties :LiveTime and :ProbeCurrent defined.
NeXLSpectrum.integrate — Functionintegrate(spec::Spectrum, channels::UnitRange{Int})
integrate(spec::Spectrum, energyRange::StepRangeLen{Float64})Sums all the counts in the specified channels. No background correction.
integrate(spec::Spectrum, back1::UnitRange{Int}, peak::UnitRange{Int}, back2::UnitRange{Int})::UncertainValue
integrate(spec::Spectrum, back1::StepRangeLen{Float64}, peak::StepRangeLen{Float64}, back2::StepRangeLen{Float64})::UncertainValueSums all the counts in the specified channels with background correction using the background intervals.
integrate(spec::Spectrum)Total integral of all counts from the LLD to the beam energy
NeXLSpectrum.estimatebackground — Functionestimatebackground(data::AbstractArray{Float64}, channel::Int, width::Int=5, order::Int=2)Returns the tangent to the a quadratic fit to the counts data centered at channel with width
NeXLSpectrum.modelBackground — FunctionmodelBackground(spec::Spectrum, chs::UnitRange{Int}, ash::AtomicSubShell)spec: A spectrum containing a peak centered on chs chs: A range of channels containing a peak ash: The edge (as an AtomicSubShell)
A simple model for modeling the background under a characteristic x-ray peak. The model fits a line to low and high energy background regions around chs.start and chs.end. If the low energy line extended out to the edge energy is larger than the high energy line at the same energy, then a negative going edge is fit between the two. Otherwise a line is fit between the low energy side and the high energy side. This model only works when there are no peak interference over the range chs.
modelBackground(spec::Spectrum, chs::UnitRange{Int})
modelBackground(spec::Spectrum, chs::UnitRange{Int}, ash::AtomicSubShell)spec: A spectrum containing a peak centered on chs chs: A range of channels containing a peak ash: The largest edge within the range of channels chs associated with the characteristic peak
A simple model for modeling the background under a characteristic x-ray peak. The model fits a line between the low and high energy background regions around chs.start and chs.end. This model only works when there are no peak interference over the range chs.
NeXLSpectrum.extractcharacteristic — Functionextractcharacteristic(spec::Spectrum, lowBack::UnitRange{Int}, highBack::UnitRange{Int})::Vector{Float64}Extract the characteristic intensity for the peak located within chs with an edge at ash.
NeXLSpectrum.peak — Functionpeak(spec::Spectrum, chs::UnitRange{Int}, ash::AtomicSubShell)::Float64Estimates the peak intensity for the characteristic X-ray in the specified range of channels.
NeXLSpectrum.background — Functionbackground(spec::Spectrum, chs::UnitRange{Int}, ash::AtomicSubShell)::Float64Estimates the background intensity for the characteristic X-ray in the specified range of channels.
NeXLSpectrum.peaktobackground — Functionpeaktobackground(spec::Spectrum, chs::UnitRange{Int}, ash::AtomicSubShell)::Float64Estimates the peak-to-background ratio for the characteristic X-ray intensity in the specified range of channels which encompass the specified AtomicSubShell.
peaktobackground(ffr::FilterFitResult, backwidth::Float64=10.0)::Float64The peak-to-background ratio as determined from the raw and residual spectra integrated over the fit region-of-interest and scaled to backwidth eV of continuum (nominally 10 eV).
NeXLSpectrum.estkratio — Functionestkratio(unk::Spectrum, std::Spectrum, chs::UnitRange{Int})Estimates the k-ratio from niave models of peak and background intensity. Only works if the peak is not interfered.
Miscellaneous Functions
NeXLSpectrum.details — Functiondetails(io, spec::Spectrum)
details(spec::Spectrum)Outputs a description of the data in the spectrum.
NeXLSpectrum.commonproperties — Functioncommonproperties(specs::AbstractArray{Spectrum})
commonproperties(props1::Dict{Symbol,Any}, props2::Dict{Symbol,Any})Return the properties that are held in common by all the spectra.
NeXLSpectrum.maxspectrum — Functionmaxspectrum(specs::AbstractArray{Spectrum})
maxspectrum(specs::Spectrum...)
maxspectrum(spec1::Spectrum, spec2::Spectrum)Compute the max-pixel spectrum for the specified spectra.
Base.findmax — FunctionBase.findmax(spec::Spectrum, chs::UnitRange{Int})
Base.findmax(spec::Spectrum)Returns the (maximum intensity, channel index) over the specified range of channels