You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In this tutorial we will perform a simple fit with pyElli.
4
+
We determine the thickness of a silicon dioxide layer on top of silicon.
5
+
This fit is often carried out as calibration and benchmark fit for ellipsometers and
6
+
is widely used for quality control of silicon wafers.
7
+
Here, we will use it to make our first steps with pyElli.
8
+
9
+
Please make sure you meet the following prerequesits:
10
+
11
+
- You are in a python environment with pyElli [installed](../index.md).
12
+
- We recommend to run the code in a jupyter or jupyter compatible environment.
13
+
However, you _can_ run this code in a repl or python file directly as well.
14
+
It will just not display the fitting widgets.
15
+
- An understanding of ellipsometry, in particular Psi/Delta measurement data.
16
+
17
+
## Importing the packages
18
+
19
+
First, we need to import pyElli itself.
20
+
Additionally, we import the `ParamsHist` class, which is a small wrapper around lmfit's `Parameter` class.
21
+
It stores a parameter history to retrieve previous fit configurations.
22
+
We'll also import the function `fit` from pyEllis fitting module.
23
+
This is a function decorator, which we will use to display our interactive fitting widget.
24
+
3
25
```python
4
26
import elli
5
27
from elli.fitting import ParamsHist, fit
6
28
```
7
29
8
30
## Reading data
9
31
32
+
We need some measurement data to perform a fit on and load an example [data set](https://github.com/PyEllips/pyElli/blob/master/examples/Basic%20Usage/SiO2onSi.ellips.nxs) of a psi delta measurement in the standardized [NeXus format](https://manual.nexusformat.org/classes/contributed_definitions/NXellipsometry.html#nxellipsometry) with pyElli's included `read_nexus_psi_delta` function.
33
+
Lets select a measurement angle of 70 degrees (`.loc[ANGLE]`) from the data and
34
+
restrict the wavelength range in between 210 nm and 800 nm (`.loc[210:800]`).
35
+
The restriction is necessary because we're using tabulated literature values for silicon, which are only provided in this wavelength range.
We have a silicon substrate which we load from the included [refractiveindex.info](https://refractiveindex.info) material database.
68
+
We are going to use the tabulated values from [Aspnes et al.](https://refractiveindex.info/?shelf=main&book=Si&page=Aspnes).
69
+
28
70
```python
29
71
rii_db = elli.db.RII()
30
72
Si = rii_db.get_mat("Si", "Aspnes")
31
73
```
32
74
33
-
## Building the Fitting Model
75
+
For the silicon dioxide layer we need a formula to insert our fitting values.
76
+
Here, we could also use tabulated values since we won't vary the parameters of the Cauchy model but in general it's a good practice to fit the material parameters, too.
34
77
35
78
```python
36
79
SiO2_dispersion = elli.Cauchy(
37
-
params["SiO2_n0"],
38
-
params["SiO2_n1"],
39
-
params["SiO2_n2"],
40
-
params["SiO2_k0"],
41
-
params["SiO2_k1"],
42
-
params["SiO2_k2"],
80
+
params["SiO2_n0"], params["SiO2_n1"], 0, 0, 0, 0,
43
81
)
44
82
```
45
83
84
+
The above snippet created a dispersion and now we need to generate a material from it. For anisotropic materials this can be done by calling `get_mat()`.
85
+
46
86
```python
47
87
SiO2 = SiO2_dispersion.get_mat()
48
88
```
49
89
90
+
Now, we we put our materials together in a `Structure`.
91
+
It consists of a front-layer, which is air (`elli.AIR`) in this case (but will be air in most experiments you do) and a back layer which is silicon here.
92
+
In between is the most important part: the array of layers.
93
+
Here, we only have a single layer of silicon dioxide.
94
+
In the `Layer` specify the material and the thickness (`SiO2_d`).
95
+
50
96
```python
51
97
structure = elli.Structure(
52
98
elli.AIR,
@@ -55,22 +101,25 @@ structure = elli.Structure(
55
101
)
56
102
```
57
103
104
+
In the last step we just need to evaluate our model for a set of wavelengths (`lbda`) at a given angle (`ANGLE`).
105
+
Additionally, we need the specify the solver (`elli.Solver2x2` in this case).
In this section we simply put the parts together: building the materials, the structure and evaluating it with the appropriate parameters.
114
+
We use the `@fit` decorator here, which takes the measurement data `psi_delta` and our fit parameter class `params`.
115
+
The `@fit` decorator generates a fit class to perform fitting on.
116
+
If this code snippet is executed in a jupyter environment it will display a fit widget in which you can alter the parameter and see the direct feedback as well as performing the fit.
By calling `fit()` we perform the fit and with `plot()` we can generate a plot of the resulting fit.
135
+
This part is optional if you used the fitting widget of the `@fit` decorator, since the widget will call these for you.
85
136
```python
86
137
fit_stats = model.fit()
87
138
model.plot()
88
-
```
139
+
```
140
+
141
+
Finally, we extract the actual thickness of the silicon dioxide layer by extracting the parameter from `fit_stats`.
142
+
```
143
+
fit_stats.params["SiO2_d].value
144
+
```
145
+
146
+
It should return a value $\approx 2.066\,\text{nm}$.
147
+
148
+
## Congrats 🎉
149
+
150
+
You have sucessfully performed a simple fit with pyElli.
151
+
Feel free to explore with this code, e.g., you may want to try varying the material parameters during the fit or using different angles from the measurement (50 or 60 degrees is also available).
0 commit comments