Skip to content

Reach point of modelling HOQI in Finesse with polarisation

Daniel Brown requested to merge feature/polarisation-plane-simple into develop

What does this MR do and why?

This merge request should bring polarisation features to the point of being able to model the HOQI interferometer, which is just plane wave, no optical cavity with polarisation.

  • Merge in Luise's code for the Jones matrices, separate module in
    • finesse.utitilies.jones.matrices for matrices
    • finesse.utitilies.jones.visualization for visualization (could be moved to plotting)
    • finesse.utitilies.jones.detectors some utilities for interpreting jones vectors (maybe unnecessary?)
  • New components/detectors
    • Add quarter-wave plate
    • PBS
      • Fix optical_equations to allow pol specific coupling equations
    • Polarisers
    • Add polarimeter detector
  • Fix power detector calculations to loop over both polarisations when enabled, see POL_IDX placeholder in the code
  • Add example/test of HOQI
  • Fix tests/validation/graph/test_single_cavity.py which requires fixing the graph solver to work with no polarisation again
  • Add a new 'physics of Finesse' page for polarisation, in this should be a page on definitions of coordinate systems and minus signs, whether any circular polarisation is defined looking into or with the beam, etc.

Math sources

Are being collected here https://gitlab.nikhef.nl/finesse/polarisation (you might need permission to access). Contains math sources for jones matrices mentioned in the docstrings, Luise's original Jones library and some mockup finesse code that we hope to run when this branch is finished.

Testing guide

New optical elements:

  • hwp (halfwaveplate)
  • qwp (quarterwaveplate)
  • lpol (linear polarizer)

All elements have a Jones matrix associated with them in their optical_equations method, the matrices are defined in finesse.utilities.jones.matrices.py

All these elements have a parameter theta , which is a rotation angle measured from the horizontal (S) plane.

Our current definition seems to be that the Jones vector is (Ex, Ey) / (S, P) !

Laser set up

Either l l1 pol=s or l l1 pol=p. You can not use polarization components if you do not specify the laser polarization (should be a check for this)

Measuring

Power detectors measure the combined s and p fields.

You have to use amplitude detectors with kwargs f=0 pol=s or f=0 pol=p to measure either S or P field

Visualization

I added a convenience method Model.add_pol_detector(node) which adds two amplitude detectors with an autogenerated names at the selected node. Their output is available in the solution object under sol.jones(node) which provides the array of (S, P) vectors for every point of the action used. This can serve as direct input for Luise's visualization methods draw_jones_animated and draw_jones_field

Examples:

Remove all signal with a linear polarizer orthogonal to the laser polarization

import finesse

model = finesse.script.parse(
    f"""
    l l1 pol=p
    lpol lp1 theta=0
    ad P lp1.p2.o f=0 pol=p
    ad S lp1.p2.o f=0 pol=s
    link(l1, lp1)
    """
)
sol = model.run()

assert sol['S'] == 0
assert sol['P'] == 0

Rotating a linear polarizer

import finesse
from matplotlib import pyplot as plt
from finesse.analysis.actions import Xaxis

model = finesse.script.parse(
    f"""
        l l1 pol=s
        lpol lp1 theta=0
        link(l1, lp1)

        ad P lp1.p2.o f=0 pol=p
        ad S lp1.p2.o f=0 pol=s
        """
)
sol = model.run(Xaxis(model.lp1.theta, "lin", 0, 360, 360))
sol.plot()

image.png

inspecting polarization state after halfwaveplate

from finesse.utilities.jones import draw_jones_field, draw_jones_animated
from matplotlib import pyplot as plt

model = finesse.script.parse(
    f"""
        l l1 pol=s
        hwp hwp1
        link(l1, hwp1)
        """
)
node = "hwp1.p2.o"
model.add_pol_detector(node)

sol = model.run()

draw_jones_field(sol.jones[node])
plt.show()

image.png

producing circular polarization with a quarterwaveplate

from finesse.utilities.jones import draw_jones_field, draw_jones_animated
from matplotlib import pyplot as plt

model = finesse.script.parse(
    f"""
        l l1 pol=s
        qwp qwp1 theta=45
        link(l1, qwp1)
        """
)
node = "qwp1.p2.o"
model.add_pol_detector(node)

sol = model.run()

# can be made interactive by adding '%matplotlib widget' to the top of your notebook
draw_jones_field(sol.jones[node])
plt.show()
# can also directly be displayed in jupyer environment
anim = draw_jones_animated(sol.jones[node])
anim.save("circular.mp4")

image.png

circular.mp4

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

  • Includes tests for added/modified code
  • Added or modified the documentation if relevant
  • Docstrings added/modified for new/modified functions
  • Committer/reviewer has ran the documentation stage when ready to merge
Edited by Miron van der Kolk

Merge request reports