In [1]:
%run pykat_notebook_defaults.py 
pykat.init_pykat_plotting() 
                                              ..-
    PyKat 1.0.19          _                  '(
                          \`.|\.__...-""""-_." )
       ..+-----.._        /  ' `            .-'
   . '            `:      7/* _/._\    \   (
  (        '::;;+;;:      `-"' =" /,`"" `) /
  L.        \`:::a:f            c_/     n_'
  ..`--...___`.  .    ,  
   `^-....____:   +.      www.gwoptics.org/pykat

Imported matplotlib.pyplot as plt
Imported numpy as np
You can now use 'print(kat)' to display the Finesse code of a 'kat' object

Introduction to Jupyter Notebooks, Pykat, and Finesse

This is the first introduction notebook for the simulation sessions this week. This week we aim to introduce you to modelling gravitational wave detectors with Finesse. By the end of the week we hope to have taught you how to produce your own quantum noise limited sensitivity for a gravitational wave detector.

These sessions together will cover the following material:

  • Fabry-Perot interferometers
  • Michelson interferometer
  • Noise couplings
  • Quantum noise

Important reference material:

The topics of the first session today are:

  • Introduction to software Python, Pykat and Finesse
  • Introduction to interferometers simulation

Installing Software

You should have received instructions on how to install Python, Pykat, Finesse and these notebook files already. If these did not install correctly we will find out today and can hopefully fix that.

Let's Get Started: Python and Jupyter Notebooks

We are going to use the Python programming language, executed in the Jupyter notebooks. We have no time to study either of these in detail during the SIM sessions. I have provided some basic introduction and links for more information below.

Python

Python is a powerful programming language which is particularly useful for fast development and scripting. We will use only a very small subset of Python's functionality. In particular, we will do simple mathematical operations (using the package Numpy), some simple string operations and we will plot output data.

I recommend that you do not try to learn Python in general right now, but search the web for a solution for each particular task. A good starting point, for example, is the A Crash Course in Python for Scientists.

More info can be found in:

The Jupyter Notebook

Text Cells

These cells are just text, fomatted using Markdown: http://daringfireball.net/projects/markdown/syntax

Code Cells

Code cells are the main element in the Jupyter notebook. When you press 'shift+enter' the content of the cell will be evaluated as Python code and an output cell is created to display the result, see the simple examples below.

In [6]:
# Adding numbers
a=5
b=10
print(a+b)
15
In [7]:
# Joining strings together
one='red '
two='car'
print(one+two)
red car
In [8]:
# Outputting sentences
r = 2
area = np.pi * r*r
print("This is a good way to present results: The area is {0:.1f} km^2".format(area))
This is a good way to present results: The area is 12.6 km^2

Latex and HTML

You can use HTML commands and Latex commands (for example: $\Delta L = L_X - L_Y$) in the markdown cells. You can also generate HTML text with code, for example to highlight certain data:

In [9]:
a=5.512;
h=HTML('<b>This is bold: {0}</b>'.format(a));
display(h)
This is bold: 5.512

Displaying Graphics (SVG File)

For any optical simulation it is very useful to prepare a sketch of the optical layout. We typically use Inkscape and the ComponentLibrary to prepare such sketches as Scalable Vector Graphics (svg files). Such files can be loaded into notebooks as shown below.

In [10]:
HTML('<img src="michelson01.svg" width=400 height=400/>')
Out[10]:

Plotting

Python provides a number of powerful plotting packages. We will be using inline plots based on the 'matplotlib' package. Examples and documentation can be found online, for example a notebook with good plotting examples, or this extensive lecture on plotting. A simple example is shown below.

In [11]:
x=np.linspace(1, 100, 10) # this creates a data vector with 10 elements

print("x = {0}".format(x))

y = x*x

plt.plot(x, y)
plt.title('A simple function')
plt.xlabel('x [some units]')
plt.ylabel('y [some other units]')
x = [   1.   12.   23.   34.   45.   56.   67.   78.   89.  100.]
Out[11]:
<matplotlib.text.Text at 0x10fef53c8>

Important: If your plots are looking too big or too small then you will need to change the DPI setting to suit your monitor. At the top of this page is a line of code that looks like pykat.init_pykat_plotting(dpi=90), either increase of decrease this to find a scaling that suits you.

Finesse and Pykat

Finesse is an interferometer simulation software, developed for the design and commissioning of laser-interferometric gravitational wave detectors. As such it is optimised for modelling the main interferometers of LIGO, Virgo, GEO etc, but it is also a simple and versatile tool to learn basic laser optics. Examples and an extensive manual for Finesse can be found on the Finesse page.

PyKat is a Python wrapper for the interferometer simulation Finesse. This allows us to run Finesse from an Jupyter notebook. The main advantage of using Finesse in this way is that Python offers the ability to do post-processing of the Finesse output very easily in the notebook.

You should have a read of this notebook:

It should be used as a reference on how to use Pykat throughout this school.

Simple Finesse and Pykat Example

Here we construct a simple Finesse model of a laser beam shining on a mirror. In this simulation we just vary the input laser power and see how much is reflected and transmitted. To measure the laser power we put two photodiodes on reflection and transmission at the mirror.

In [13]:
kat = finesse.kat()
kat.verbose = False

code = """
l laser1 1.0 0 n1 
s s1 0 n1 n2

pd Prefl n2
pd Ptran n3

m m1 0.9 0.1 0 n2 n3

xaxis laser1 P lin 0 1 10
yaxis abs 
"""

kat.parseCommands(code)

out1 = kat.run()

The data can be plotted in multiple ways. If quickly want to see the results we suggest using the builtin plotting command for the output:

In [14]:
# Plotting the results of an output can be done using the builtin command
fig = out1.plot()

This will produce a plot using all the detectors enabled in the model. It should be noted that the yaxis units is [au] because multiple quantities can be shown at the same time. For example, a beam's power in Watts can be plotted along with the size of a beam. Thus to infer the units of a trace you must look at what type of detector has been used.

The builtin plotting function has many options that can be set to customise the plot. For more examples on using this please see the notebook on plotting.

However, if you would rather make a plot yourself you can always just use matplotlib commands as per usual:

In [15]:
plt.plot(out1.x, out1["Prefl"], label="Refl")
plt.plot(out1.x, out1["Ptran"], label="Tran")

plt.xlim(out1.x.min(), out1.x.max())

plt.ylabel("Power [W]")
plt.xlabel("Laser power [W]")
plt.legend()
Out[15]:
<matplotlib.text.Text at 0x10feb0208>

The out object returned by run() command is an important one as it contains all the results from the simulation. It is important to remember that when Finesse outputs some results it is just an array of numbers: the number of steps in the simulation set with the xaxis and the outputted value of each of the detectors you have added.

You can see the raw outputs with:

In [16]:
print(out1.x) # show the xaxis values
print(out1.y) 
[ 0.   0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1. ]
[[ 0.    0.  ]
 [ 0.09  0.01]
 [ 0.18  0.02]
 [ 0.27  0.03]
 [ 0.36  0.04]
 [ 0.45  0.05]
 [ 0.54  0.06]
 [ 0.63  0.07]
 [ 0.72  0.08]
 [ 0.81  0.09]
 [ 0.9   0.1 ]]

As you can see, they are quite long and not easily readable. Here we just have one detector, however, if we have more we would have more columns of data. To find out which column is which you need to look at the out.ylabels array:

In [17]:
print(out1.ylabels)
['Prefl', 'Ptran']

However, the recommended method for accessing the values of a particular detector is by using the detector's name as shown here:

In [18]:
out1["Prefl"]
Out[18]:
array([ 0.  ,  0.09,  0.18,  0.27,  0.36,  0.45,  0.54,  0.63,  0.72,
        0.81,  0.9 ])

Your Tasks

In each notebook we will provide some tasks for you to complete. You should make a local copy of this notebook that you will edit. In each task section you should add your code you write to compelte the task. After the sessions we will have a show and tell from some students about how they did each task.

The following sections provide some simple tasks to get you back up and running with Finesse and Pykat. The aim here is not to full understand the simulation but to just get something running.

You should help each other, work in groups, organise yourselves and don't forget to ask for help if needed!

Task 1: Copy and run an exisiting Finesse example

Don't worry about understanding any physics here, this example is just about getting something running correctly before we proceed.

(a) Copy the Finesse code for radiation pressure effects from the Finesse pages

(b) Load this into a kat object as shown about and run it

In [2]:
model = finesse.kat()
model.parseCommands("""
# optical setup: laser, space and mirror:
l l1 1 0 n1
s s1 1 n1 n2
m m1 1 0 0 n2 n3
 
# define transfer function with pole at 10Hz and Q factor 1000
tf pendulum 1 0 p 10 1000
# apply transfer function to mirror as force->motion
attr m1 mass 1 zmech pendulum     
 
# measuring the mirror longitudinal motion
xd m1_z m1 z
 
# generate amplitude modulation at the laser 
fsig sig1 l1 amp 1 0
 
xaxis sig1 f log 1 100 400
yaxis log abs:deg
""")

out = kat.run()
--------------------------------------------------------------
Running kat - Started at 2017-07-10 05:39:06.678099

Finished in 0.160533 seconds
100% | ETA:  0:00:00 | Calculating                                             

Task 2: Plot the results from Task 1

Take the output generated when running the kat object made in task 1 and plot all the outputs.

In [4]:
fig = out.plot()
In [ ]: