"""
cavity.py - A Cavity class and related functions for representing a Fabry-Perot cavity
"""
#{{{ Import modules
import numpy as np
pi = np.pi
c = 299792458.0
sqrt = np.lib.scimath.sqrt
import gtrace.optics.gaussian as gauss
from enthought.traits.api import CFloat, HasTraits
#}}}
#{{{ Class Cavity
[docs]class Cavity(HasTraits):
"""
A class to represent a Fabry-Perot cavity.
*Attributes*
**r1:** Input mirror reflectivity (amplitude)
**r2:** End mirror reflectivity (amplitude)
**rp1:** Input mirror reflectivity (power)
**rp2:** End mirror reflectivity (power)
**L:** Length
**R1:** ROC of the input mirror (positive when concave to incident light, i.e.
convex seen from inside the cavity)
**R2:** ROC of the end mirror (positive when concave to incident light, i.e.
concave seen from inside the cavity)
**wl:** Wavelength
"""
r1 = CFloat(0.9)
r2 = CFloat(0.99)
rp1 = CFloat()
rp2 = CFloat()
tp1 = CFloat()
tp2 = CFloat()
t1 = CFloat()
t2 = CFloat()
L = CFloat(1.0)
R1 = CFloat(-1.5)
R2 = CFloat(1.5)
g1 = CFloat()
g2 = CFloat()
wl=CFloat()
def __init__(self, r1=0.9, r2=0.99, L=1.0, R1=-1.5, R2=1.5, wl=1064e-9, power=False):
"""
**r1:** Input mirror reflectivity
**r2:** End mirror reflectivity
**L:** Length
**R1:** ROC of the input mirror (positive when concave to incident light, i.e.
convex seen from inside the cavity)
**R2:** ROC of the end mirror (positive when concave to incident light, i.e.
concave seen from inside the cavity)
**wl:** Wavelength
**power:** If True, r1 and r2 are treated as power reflectivities.
Otherwise, r1 and r2 are regarded as amplitude reflectivities.
"""
if power:
self.r1 = np.sqrt(r1)
self.r2 = np.sqrt(r2)
else:
self.r1 = r1
self.r2 = r2
self.L = L
self.R1 = R1
self.R2 = R2
self.wl = wl
#{{{ Trait change handlers
def _R1_changed(self, old, new):
self.g1 = 1 + self.L/new
def _R2_changed(self, old, new):
self.g2 = 1 - self.L/new
def _L_changed(self, old, new):
self.g1 = 1 + new/self.R1
self.g2 = 1 - new/self.R2
def _r1_changed(self, old, r1):
self.rp1 = r1**2
self.tp1 = 1 - self.rp1
self.t1 = np.sqrt(self.tp1)
def _r2_changed(self, old, r2):
self.rp2 = r2**2
self.tp2 = 1 - self.rp2
self.t2 = np.sqrt(self.tp2)
#}}}
[docs] def finesse(self):
'''
Returns the finesse of the cavity.
'''
return finesse(self.r1, self.r2)
[docs] def storageTime(self):
'''
Storage time
'''
return 2*self.L*self.finesse()/(2*pi*c)
[docs] def pole(self):
'''
Cavity pole frequency [Hz]
'''
return 1/(2*pi*self.storageTime())
[docs] def Nbounce(self):
'''
Bounce number
'''
return 2*self.finesse()/pi
[docs] def powerGain(self):
'''
Ratio of the intra-cavity power to the input power.
'''
return (self.t1/(1-self.r1*self.r2))**2
[docs] def FSR(self):
'''
Returns the free spectral range of the cavity.
'''
return c/(2*self.L)
[docs] def modeSpacing(self):
'''
Return the transverse mode spacing of the cavity (commonly called gamma).
It is a fractional number defined by gamma = (mode spacing frequency)/FSR.
'''
return gauss.modeSpacing(self.g1, self.g2)
[docs] def waist(self, size=False):
"""
Return the q-parameter or the radius of the beam at the cavity waist.
*Input arguments*
**size:** (optional) if set to true, the first element of the returned tuple will be the waist size, rather than the q-parameter.
*==Returned parameters ==*
**(q0, d):** This function returns a tuple with two elements.
The first element is the q-parameter of the cavity mode at
the cavity waist. If size=True is given, it becomes the waist
size (1/e^2 radius).
The second element is the distance of the cavity waist from
the input mirror.
"""
# q0 = 1j*np.sqrt(self.L)*np.sqrt(-(self.L+self.R1)*(self.L-self.R2)\
# *(self.L+self.R1-self.R2))\
# /(2*self.L+self.R1-self.R2)
q0 = 1j*sqrt(-self.L*(self.L+self.R1)**2*(self.L-self.R2)*\
(self.L+self.R1-self.R2)/((-2*self.L-self.R1+self.R2)**2))\
/sqrt(self.L+self.R1)
d = self.L*(self.L-self.R2)/(2*self.L+self.R1-self.R2)
if size:
return (gauss.q2w(q0, wl=self.wl), d)
else:
return (q0, d)
[docs] def spotSize(self):
"""
Returns the beam spot sizes on the input and end mirrors
as a tuple (w1,w2).
"""
(q0,d) = self.waist()
w1=gauss.q2w(q0-d, wl=self.wl)
w2=gauss.q2w(q0+self.L-d, wl=self.wl)
return (w1, w2)
[docs] def trans(self, f=0, d=0):
"""
Returns the amplitude transmissivity of the cavity.
It assumes the cavity was locked to the incident light first. Then computes the
amplitude transmissivity for the light with a frequency shift f from the original light
with the cavity length changed by d from the initial state.
*== Input arguments ==*
**f:** Frequency shift of the light in Hz.
**d:** Cavity length detuning in m.
*== Returned parameter ==*
The amplitude transmissivity of the cavity (a complex number).
"""
#One way phase change
phi=2*pi*(self.L*f/c + d/self.wl + d*f/c)
return self.t1 * self.t2 * np.exp(-1j*phi)/\
(1-self.r1*self.r2*np.exp(-2j*phi))
[docs] def refl(self, f=0, d=0):
"""
Returns the amplitude reflectivity of the cavity.
It assumes the cavity was locked to the incident light first. Then computes the
amplitude reflectivity for the light with a frequency shift f from the original light
with the cavity length changed by d from the initial state.
*== Input arguments ==*
**f:** Frequency shift of the light in Hz.
**d:** Cavity length detuning in m.
*== Returned parameter ==*
The amplitude reflectivity of the cavity (a complex number).
"""
#One way phase change
phi=2*pi*(self.L*f/c + d/self.wl + d*f/c)
return -self.r1+self.t1**2 * self.r2 *np.exp(-2j*phi)/\
(1-self.r1*self.r2*np.exp(-2j*phi))
[docs] def intra(self, f=0, d=0):
"""
Returns the intra cavity field amplitude.
It assumes the cavity was locked to the incident light first. Then computes the
intra-cavity field amplitude for the light with a frequency shift f from the original light
with the cavity length changed by d from the initial state.
*== Input arguments ==*
**f:** Frequency shift of the light in Hz.
**d:** Cavity length detuning in m.
*== Returned parameter ==*
The intra-cavity field amplitude at the input mirror surface (a complex number).
"""
#One way phase change
phi=2*pi*((self.L+d)*f/c + d/self.wl)
return self.t1/(1-self.r1*self.r2*np.exp(-2j*phi))
#}}}
#{{{ Often used parameters
[docs]def finesse(r1, r2, power=False):
'''
Returns the finesse of a cavity
'''
if power:
r1 = np.sqrt(r1)
r2 = np.sqrt(r2)
return pi*np.sqrt(r1*r2)/(1-r1*r2)
#}}}