{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Multilayer fit\n\nFits a multilayer model to an ALD grown TiO2 sample on SiO2 / Si.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import elli\nfrom elli.fitting import ParamsHist, fit"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Load data\n\nLoad data collected with Sentech Ellipsometer and cut the spectral range (to use Si Aspnes file)\n\nThe sample is an ALD grown TiO2 sample (with 400 cycles)\non commercially available SiO2 / Si substrate.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "tss = elli.SpectraRay.read_psi_delta_file(\"TiO2_400cycles.txt\").loc[400:800]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Set start parameters\nHere we set the start parameters for the TiO2 and SiO2 layer.\nWe set the SiO2 layer parameters to a fixed value from another\nfit of the substrate. See the `Basic usage` example for details\non how to perform such a fit.\nIn general it is a good idea to fit your data layer-wise if possible\nto yield a better fit quality.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "params = ParamsHist()\nparams.add(\"SiO2_n0\", value=1.452, min=-100, max=100, vary=False)\nparams.add(\"SiO2_n1\", value=36.0, min=-40000, max=40000, vary=False)\nparams.add(\"SiO2_n2\", value=0, min=-40000, max=40000, vary=False)\nparams.add(\"SiO2_k0\", value=0, min=-100, max=100, vary=False)\nparams.add(\"SiO2_k1\", value=0, min=-40000, max=40000, vary=False)\nparams.add(\"SiO2_k2\", value=0, min=-40000, max=40000, vary=False)\nparams.add(\"SiO2_d\", value=276.36, min=0, max=40000, vary=False)\n\nparams.add(\"TiO2_n0\", value=2.236, min=-100, max=100, vary=True)\nparams.add(\"TiO2_n1\", value=451, min=-40000, max=40000, vary=True)\nparams.add(\"TiO2_n2\", value=251, min=-40000, max=40000, vary=True)\nparams.add(\"TiO2_k0\", value=0, min=-100, max=100, vary=False)\nparams.add(\"TiO2_k1\", value=0, min=-40000, max=40000, vary=False)\nparams.add(\"TiO2_k2\", value=0, min=-40000, max=40000, vary=False)\n\nparams.add(\"TiO2_d\", value=20, min=0, max=40000, vary=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Building the model\nHere the model is build and the experimental structure is returned.\nFor details on this process please refer to the `Basic usage` example.\nWhen executed in an jupyter notebook this displays an interactive graph\nwith which you can select the start parameters before fitting the data.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "@fit(tss, params)\ndef model(lbda, params):\n    sr = elli.SpectraRay(\"./\")\n    Si = elli.IsotropicMaterial(sr.loadDispersionTable(\"Si_Aspnes.mat\"))\n\n    SiO2 = elli.Cauchy(\n        params[\"SiO2_n0\"],\n        params[\"SiO2_n1\"],\n        params[\"SiO2_n2\"],\n        params[\"SiO2_k0\"],\n        params[\"SiO2_k1\"],\n        params[\"SiO2_k2\"],\n    ).get_mat()\n    TiO2 = elli.Cauchy(\n        params[\"TiO2_n0\"],\n        params[\"TiO2_n1\"],\n        params[\"TiO2_n2\"],\n        params[\"TiO2_k0\"],\n        params[\"TiO2_k1\"],\n        params[\"TiO2_k2\"],\n    ).get_mat()\n\n    Layer = [elli.Layer(TiO2, params[\"TiO2_d\"]), elli.Layer(SiO2, params[\"SiO2_d\"])]\n\n    return elli.Structure(elli.AIR, Layer, Si).evaluate(lbda, 70, solver=elli.Solver2x2)\n    # Alternative: Use 4x4 Solver with scipy propagator\n    # return elli.Structure(elli.AIR, Layer, Si).evaluate(lbda, 70, solver=elli.Solver4x4, propagator=elli.PropagatorExpm())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Plot & Fit model\nWe plot the model to see the deviation with the initial parameters.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "model.plot()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now lets perform the fit and plot the comparison of\ncalculation and experimental data afterwards.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fit_stats = model.fit()\nmodel.plot()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can also have a look at the fit statistics.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "fit_stats"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## References\n[Here](https://github.com/PyEllips/pyElli/tree/master/examples/TiO2%20Fit)\nyou can find the latest jupyter notebook and data files of this example.\n\n"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}