**3.Gaussian Beams > 3.Mirror maps**

**2. Preprocessing Phase Maps**

Author: Daniel TÃ¶yrÃ¤

** Recommended notebooks before you start:**

We recommend that you have looked through the notebooks that you find in the folder 03_Gaussian_beams>06_Mirror_maps. The link above only works if you started IPython/Jupyter Notebook in the top directory of this course.

**Reading material and references:**

[1] A. Freise, K. Strain, D. Brown, and C. Bond, "Interferometer Techniques for Gravitational-Wave Detection", *Living Reviews in Relativity* **13**, 1 (2010). - Living review article (more like a book) on laser interferometry in the frequency domain for detecting gravitational waves, and FINESSE.

[2] A. Freise, D. Brown, and C. Bond, "Finesse, Frequency domain INterferomEter Simulation SoftwarE". - FINESSE-manual

[3] FINESSE syntax reference - Useful online syntax reference for FINESSE. Also available in the Finesse manual [2], but this online version is updated more often.

** After this session you will be able to... **

- Make a mirror map ready for being used in FINESSE

We start by loading PyKat and other Python packages that we need:

In [1]:

```
import numpy as np # Importing numpy
import matplotlib # For plotting
import matplotlib.pyplot as plt
from pykat import finesse # Importing the pykat.finesse package
from pykat.commands import * # Importing all packages in pykat.commands.
from pykat.optics.maps import * # Importing maps package
from IPython.display import display, HTML # Allows us to display HTML.
# Telling the notebook to make plots inline.
%matplotlib inline
# Initialises the PyKat plotting tool. Change dpi value
# to change figure sizes on your screen.
pykat.init_pykat_plotting(dpi=90)
```

In [2]:

```
smap = read_map('ETM08_S1_-power160.dat', mapFormat='metroPro')
fig = smap.plot()
```

`surfacemap.notNan`

, which is a matrix of booleans keeping track of which elements in the matrix `surfacemap.data`

that are not `NaN`

.

`notNan`

field, we can see that there are actually some `NaN`

mixed in there as well.

In [3]:

```
smap1 = deepcopy(smap)
# Plotting the matrix notNan
fig = plt.figure()
pcm = plt.pcolormesh(smap1.x*100, smap1.y*100, smap1.notNan)
pcm.set_rasterized(True)
cbar = plt.colorbar()
plt.xlabel('x [cm]')
plt.ylabel('y [cm]')
plt.show(fig)
```

`True`

(not `NaN`

), and 0 is equal to `False`

(`NaN`

). So we see that there are some `NaN`

-values in the edge. Cropping without specifying a cropping radius to use the matrix `surfacemap.notNan`

to crop:

In [4]:

```
# Computing radius (max distance from center to a non-NaN element.)
r0 = smap1.find_radius(method = 'max', unit='meters')
# Cropping
smap1.crop()
# Showing unprocessed map
fig = smap1.plot()
# Computing radius (max distance from center to a non-NaN element.)
r1 = smap1.find_radius(method = 'max', unit='meters')
print('Radius before cropping: {0:.5f} m'.format(r0))
print('Radius after cropping: {0:.5f} m'.format(r1))
```

In [5]:

```
smap2 = deepcopy(smap)
r0 = smap2.find_radius(method = 'max', unit='meters')
# The specified radius of this mirror
smap2.crop(0.154)
r1 = smap2.find_radius(method = 'max', unit='meters')
fig = smap2.plot()
# Radius used in the LIGO figure measurement reports
smap3 = deepcopy(smap)
smap3.crop(0.0802)
r2 = smap3.find_radius(method = 'max', unit='meters')
fig = smap3.plot()
print('Radius before cropping: {0:.5f} m'.format(r0))
print('Radius first cropping: {0:.5f} m'.format(r1))
print('Radius second cropping: {0:.5f} m'.format(r2))
```

By keeping track of the radii we can see that the algorithm is doing what we want.

`surfacemap.xyOffet`

. We test this here:

In [6]:

```
smap4 = deepcopy(smap3)
# Setting xy-offset
smap4.xyOffset = (0.02,0.05)
# Storing center and xyoffset for printing
xy_offset1 = smap4.xyOffset
center1 = smap4.center
# Plotting, center should be at (x,y) = (-0.02, -0.05) m.
smap4.plot()
# And now we recentering.
smap4.recenter()
# Storing values for printing
xy_offset2 = smap4.xyOffset
center2 = smap4.center
# Plotting, center should be at (x,y) = (0,0) m
smap4.plot()
print(('First center (x, y) [points]: ({0[0]:.3f}, {0[1]:.3f}), ' +
'first xy-offset [m]: ({1[0]:.3f},{1[1]:.3f})').format(center1,xy_offset1))
print(('Second center (x, y) [points]: ({0[0]:.3f}, {0[1]:.3f}), ' +
'second xy-offset [m]: ({1[0]:.3f},{1[1]:.3f})').format(center2,xy_offset2))
```

`surfacemap.center`

is specified in data points, while xy-offset is specified in meters. To get the center in meters, measured from th lower left corner of mirror map above, we can multiply with the attribute `surfacemap.step_size`

:

In [7]:

```
center = (smap4.center[0]*smap4.step_size[0], smap4.center[1]*smap4.step_size[1])
print('Center (x,y): ({0[0]:.5f}, {0[1]:.5f}) m'.format(center))
```

`surfacemap.remove_curvature()`

returns and stores the information about what was removed. The Zernike-polynomial is also converted into an equivalent radius of curvature. This is an approximation, since Z(2,0) actually is parabolic, but for the large radii of curvatures used in the arm cavities of LIGO, the approximation is valid.

In [8]:

```
smap5 = deepcopy(smap4)
Rc, znm = smap5.remove_curvature(method='zernike', zModes = 'defocus')
fig5 = smap5.plot()
print('Returned removed values:')
print('Radius of curvature: {0:.2e} m'.format(Rc))
print('Zernike polynomial: {0}'.format(znm))
print()
print('Stored removed values:')
print('Radius of curvature: {0:.2e} m'.format(smap5.RcRemoved))
print('Zernike polynomial: {0}'.format(smap5.zernikeRemoved))
```

`surfacemap`

-object. Note that barely nothing was removed. This map contains very little curvature as it has already been removed by LIGO.

`zModes = 'astigmatism'`

.

In [9]:

```
smap6 = deepcopy(smap4)
Rc, znm = smap6.remove_curvature(method='zernike', zModes = 'astigmatism')
fig6 = smap6.plot()
print('Returned removed values:')
print('Radius of curvature (x,y): ({0[0]:.2e}, {0[1]:.2e}) m'.format(Rc))
print('Zernike polynomial: {0}'.format(znm))
print()
print('Stored removed values:')
print('Radius of curvature (x,y): ({0[0]:.2e}, {0[1]:.2e}) m'.format(smap6.RcRemoved))
print('Zernike polynomial: {0}'.format(smap6.zernikeRemoved))
```

We could also remove both the defocus and the astigmatism at once by using:

In [10]:

```
smap7 = deepcopy(smap4)
Rc, znm = smap7.remove_curvature(method='zernike', zModes = 'all')
smap7.plot()
print('Returned removed values:')
print('Radius of curvature (x,y): ({0[0]:.2e}, {0[1]:.2e}) m'.format(Rc))
print('Zernike polynomial: {0}'.format(znm))
print()
print('Stored removed values:')
print('Radius of curvature (x,y): ({0[0]:.2e}, {0[1]:.2e}) m'.format(smap7.RcRemoved))
print('Zernike polynomial: {0}'.format(smap7.zernikeRemoved))
```