Skip to content

Example: Fit single layer ellipsometry 1

Leandro Acquaroli edited this page Nov 28, 2019 · 3 revisions

In this example, we will fit the ellipsometry spectra of a tantalum oxide thin film coating atop a fused silica UV graded glass substrate. The light hits the air medium, then the oxide film and finally passes through the substrate.

We will use the Tauc-Lorentz parametrization of the dielectric function, with three oscillators (terms).

The complete code can be found here.

Load modules

using Optim
using Plots
pyplot()
using ThinFilmsTools

Set the light source

# Wavelength range [nm] and angle of incidence [degrees]
beam = PlaneWave(200:2100, [60.])

Layers of the system

# Refractive indices of media
incident = RIdb.air(beam.λ)
emergent = RIdb.fused_silica_uv(beam.λ)

# Define the RI model to use
layers = [
    LayerTMMO(incident),
    ModelFit(:tauclorentz),
    LayerTMMO(emergent),
]

Measured spectra from DB

Ψexp, Δexp = SpectraDB.tantala_spectrum(beam.λ)

Optimisation

We define the seed and the spectrum type to fit. First, we run the optimisation with the LBFGS() algorithm to get an estimation of the parameters., and then we run the SAMIN().

## Search
seed = [vcat(92.0, # thickness
             [1.5, 4.3, # ϵinf, Eg
              340, 5.0, 2.8, # osc 1, A1, E01, Γ1
              715, 2, 0.5, # osc 2
              41, 5, 0.8, # osc 3
             ],
        ),
]

# Spectrum type: ellipsometry with the input experimental spectra
spectype = Ellipsometry([Ψexp Δexp])

# Options for the optimisation algorithm
options = Optim.Options(
    g_abstol=1e-8, g_reltol=1e-8, iterations=10^5, show_trace=true, store_trace=false,
);

# Solve with LBFGS()
solOptim0 = fit_tmm_optics(
    spectype, seed, beam, layers;
    options=options, alg = LBFGS(), oftype=SumMeanAbs(),
)

Now we run the simulated annealing algorithm using the solution from above. We first take care of the boundaries for those critical parameters.

lb = 0.5.*solOptim0.optParams
ub = 2.0.*solOptim0.optParams
# Thickness
lb[1][1] = 0.9.*solOptim0.optParams[1][1]
ub[1][1] = 1.2.*solOptim0.optParams[1][1]
# Egap
lb[1][3] = 3.0
ub[1][3] = 6.0

solOptim = fit_tmm_optics(
    spectype, solOptim0.optParams, beam, layers;
    options=options, alg=SAMIN(), lb=lb, ub=ub, oftype=SumMeanAbs(),
)
plot(FitSpectrumEllip(),
    solOptim.beam.λ, solOptim.spectrumExp, solOptim.spectrumFit,
    xaxis=("Wavelength [nm]"),
)
gui()

Fit Single Layer TL 3 osc

Results as follow:

julia> solOptim.optParams
1-element Array{Array{Float64,1},1}:
 [92.41268518127337,
  1.294018564396567, 4.258287813517591, 
  348.0769327939244, 3.7171269504011133, 4.97982821966445, 
  574.0431000488865, 3.7406423898551893, 0.580618765881699, 
  81.73269057321525, 5.273106528658877, 1.0466795973678233]
Clone this wiki locally