-
Notifications
You must be signed in to change notification settings - Fork 5
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.
using Optim
using Plots
pyplot()
using ThinFilmsTools
# Wavelength range [nm] and angle of incidence [degrees]
beam = PlaneWave(200:2100, [60.])
# 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),
]
Ψexp, Δexp = SpectraDB.tantala_spectrum(beam.λ)
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()
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]