Fresnel Coefficients and Ellipsometric angles

This notebook explores how light gets reflected from an interface.

Fresnel Coefficients

Let's define the perpendicular and parallel Fresnel coefficients.


In [1]:
import numpy as np
def perpendicularFresnelCoefficient(n1, n2, theta):
    ci = np.cos(theta*np.pi/180)
    si = np.sin(theta*np.pi/180)
    temp1 = n1*ci
    temp2 = n2*np.sqrt(1-(n1/n2*si)**2)
    num = temp1-temp2
    den = temp1+temp2
    return num/den

def parallelFresnelCoefficient(n1, n2, theta):
    ci = np.cos(theta*np.pi/180)
    si = np.sin(theta*np.pi/180)
    temp1 = n1*np.sqrt(1-(n1/n2*si)**2)
    temp2 = n2*ci
    num = temp1-temp2
    den = temp1+temp2
    return num/den

And now the perpendicular and parallel reflectivities.


In [2]:
def perpendicularReflectivity(n1,k1,n2,k2,theta):
    return np.abs(perpendicularFresnelCoefficient(n1+k1*1j, n2+k2*1j, theta))**2

def parallelReflectivity(n1,k1,n2,k2,theta):
    return np.abs(parallelFresnelCoefficient(n1+k1*1j, n2+k2*1j, theta))**2

Now, some imports to be able to plot and handle data


In [3]:
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
output_notebook()

from bokeh.io import push_notebook
from bokeh.models import ColumnDataSource

from ipywidgets import interact


Loading BokehJS ...

To plot the reflectivities as a function of the angle of incidence we need to do some coding!

The starting point will be an interface defined by vacuum and a material with $n=1.5$ and no absorption.


In [4]:
angle = np.arange(0, 90.5, 0.5)
Rs = perpendicularReflectivity(1, 0, 1.5, 0, angle)
Rp = parallelReflectivity(1, 0, 1.5, 0, angle)
source1 = ColumnDataSource(data=dict(x=angle, y=Rs))
source2 = ColumnDataSource(data=dict(x=angle, y=Rp))
reflectivityPlot = figure(title="Reflectivity", plot_height=300, plot_width=600, y_range=(0, 1), x_range=(0,90))
reflectivityPlot.line(angle, Rs, color="#2222aa", alpha=0.5, line_width=2, source=source1, name="1")
reflectivityPlot.line(angle, Rp, color="#222222", alpha=0.5, line_width=2, source=source2, name="2")
show(reflectivityPlot, notebook_handle=True)


Out[4]:

<Bokeh Notebook handle for In[4]>

There we have the reflectivity. But it would be very interesting if we were able to interact and explore the behavior of the reflectivity given different index of refraction for the two media defining the interface.

We add interaction capability in the following.


In [5]:
def updateReflectivityPlot(n1=1, k1=0, n2=1.5, k2=0):
    source1.data['y'] = perpendicularReflectivity(n1, k1, n2, k2, angle)
    source2.data['y'] = parallelReflectivity(n1, k1, n2, k2, angle)
    push_notebook()
    
interact(updateReflectivityPlot, n1=(1, 5, 0.05), k1=(0, 2, 0.01), n2=(1, 5, 0.05), k2=(0, 2, 0.01))

Ellipsometric Angles

At this point, we can see how the ellipsometric angles behave.

First we define the ellipsometric angles by using the previously defined Fresnel coefficients and then some similar code for plotting and handling the interactivity as for the reflectivity before.


In [6]:
def ellipsometricAngles(n1, n2, angle):
    rp = parallelFresnelCoefficient(n1, n2, angle)
    rs = perpendicularFresnelCoefficient(n1, n2, angle)
    psi = np.arctan(np.abs(rp)/np.abs(rs))*180/np.pi
    delta = np.angle(rp, deg=True)-np.angle(rs, deg=True)
    
    return psi, delta

In [7]:
psi, delta = ellipsometricAngles(1, 1.5, angle)
source1 = ColumnDataSource(data=dict(x=angle, y=psi))
#source2 = ColumnDataSource(data=dict(x=angle, y=delta))
ellipsometryPlot = figure(title="Psi and Delta", plot_height=300, plot_width=600, y_range=(0, 50), x_range=(0,90))
ellipsometryPlot.line(angle, psi, color="#2222aa", alpha=0.5, line_width=2, source=source1, name="1")
#ellipsometryPlot.line(angle, delta, color="#222222", alpha=0.5, line_width=2, source=source1, name="2")

def updateEllipsometryPlot(n1=1, k1=0, n2=1.5, k2=0):
    source1.data['y'] = ellipsometricAngles(n1+1j*k1, n2+1j*k2, angle)[0]
    #source2.data['y'] = ellipsometricAngles(n1+1j*k1, n2+1j*k2, angle)[1]
    push_notebook()
    
show(ellipsometryPlot, notebook_handle=True)


Out[7]:

<Bokeh Notebook handle for In[7]>


In [8]:
interact(updateEllipsometryPlot, n1=(1,5, 0.05), k1=(0, 2, 0.01), n2=(1,5, 0.05), k2=(0, 2, 0.01))