-
Notifications
You must be signed in to change notification settings - Fork 5
Example: Fit two layers with separating layer in between (demo)
Leandro Acquaroli edited this page Nov 28, 2019
·
3 revisions
Here we show how to fit the parameters of the two layers separated by another one that is not fitted. We will construct a theoretical transmittance spectrum and fitted using two different models for each layer of interest.
The complete code can be found here.
# Load modules
using Plots, LaTeXStrings
pyplot()
using ThinFilmsTools
using OptimWe create a function to create a fictitious spectrum of transmittance that will serve for the fitting procedure. The layers that we will fit are indicated with a and b.
##
function glass_transmittance(beam, incident, emergent)
layers = [
LayerTMMO(incident),
LayerTMMO(RI.looyenga([0.5 0.5],[RIdb.air(beam.λ) RIdb.silicon(beam.λ)]); d=100.), #a
LayerTMMO(RIdb.glass(beam.λ./1e3); d=300.),
LayerTMMO(RIdb.glass(beam.λ./1e3); d=100.), #b
LayerTMMO(emergent),
]
sol = tmm_optics(beam, layers)[1]
return vec(beam.p.*sol.Tp .+ (1.0 - beam.p).*sol.Ts)
end
### Wavelength range [nm]
λ = 400:1000
# Angle of incidence [degrees]
θ = [5.]
# Polarisation (1.0 = p, 0.0 = s, between 0.0 and 1.0 = average)
pol = 0.5
beam = PlaneWave(λ, θ; p=pol)We define the indices of refraction and the layers, where we choose the second and fourth as the ones to be fitted.
# Refractive indices of incident (0) and substrate (2)
incident = RIdb.air(beam.λ)
emergent = RIdb.silicon(beam.λ)
# Define the RI model to use
layers = [
LayerTMMO(incident), # 1
ModelFit(:looyenga; N=(ninc=incident, nhost=emergent)), # 2
LayerTMMO(RIdb.glass(beam.λ./1e3); d=300.), # 3
ModelFit(:cauchyurbach), # 4
LayerTMMO(emergent), # 5
]Texp = glass_transmittance(beam, incident, emergent)options = Optim.Options(
g_abstol=1e-8, g_reltol=1e-8, iterations=10^5, show_trace=true, store_trace=false,
);
# Seeds of the ModelFit that appears in layers. The order here matters
# and the elements in each seed must match the number of elements
# accepted in the ModelFit layer used
seed = [
[100.0, 0.5], # intial guess for :looyenga model, layers[2]
[100.0, 1.5, 0.23, 1.0, 0.0, 1.0, 1.0], # intial guess for :cauchyurbach model, layers[4]
]
solOptim = fit_tmm_optics(
Transmittance(Texp), seed, beam, layers;
options=options, alg=SAMIN(), lb=0.5.*seed, ub=1.5.*seed,
)
plot(FitSpectrum(),
solOptim.beam.λ, solOptim.spectrumExp, solOptim.spectrumFit,
xaxis=("Wavelength [nm]"),
yaxis=("Transmittance"),
)
gui()
The results can be seen by typing
julia> solOptim.objfunMin
2.0852427777269855e-7
julia> solOptim.optParams
2-element Array{Array{Float64,1},1}:
[100.20261188423837, 0.5009380743144798]
[100.01313444247826, 1.5059167041688846, 0.1150000000000001, 0.5000000000000016, 0.0, 0.6175516492383015, 1.23581135410979]