Commit 077834d3 authored by Daniel Brown's avatar Daniel Brown
Browse files

adding in beam trace, bp and gouy detectors

parent 377585ad
import pykat
from pykat.utilities.plotting.beamtrace import plot_beam_trace
import numpy as np
import pylab
import copy
kat = pykat.finesse.kat()
cmds = """
l l1 1 0 n0
s s0 1000 n0 n1
m m1 0.5 0.5 0 n1 n2
s s1 10 n2 n3
m m2 0.5 0.5 0 n3 n4
s s2 20 n4 n5
bs bs1 0.5 0.5 0 0 n5 n6 n7 n8
s s3 20 n6 n9
s s4 20 n7 n10
s s5 20 n8 n11
bs bs2 0.5 0.5 0 0 n9 n12 n13 n14
s s6 3 n12 n15
lens lens1 20 n15 n16
s s7 500 n16 n17
gouy g1 x s0 s1 s2
bp bp1 x w0 n5
gauss g1 l1 n0 8e-3 -1000 4e-3 -1200
noxaxis
maxtem 0
"""
kat.parseCommands(cmds)
plot_beam_trace(kat, 'n0', 'n17')
\ No newline at end of file
from pykat.utilities.maps import *
smap = read_map('lens_map.txt')
smap.plot()
......@@ -14,9 +14,10 @@ from pykat.param import Param
import pykat.exceptions as pkex
import warnings
import copy
class Detector(object) :
def __init__(self, name,node):
def __init__(self, name, node=None):
self.__name = name
self._svgItem = None
self._kat = None
......@@ -28,6 +29,7 @@ class Detector(object) :
self._mask = {}
self.__scale = None
self.__removed = False
self.__requested_node = None
if node != None:
if node[-1]=='*':
......@@ -151,7 +153,111 @@ class ad(Detector):
rtn.extend(p.getFinesseText())
return rtn
class gouy(Detector):
def __init__(self, name, direction, spaces):
Detector.__init__(self, name)
self.spaces = copy.copy(spaces)
self.direction = direction
self.alternate_beam = False
@property
def direction(self): return self.__dir
@direction.setter
def direction(self, value):
if value == None or (value != 'x' and value != 'y'):
raise pkex.BasePyKatException('Direction must be either x or y')
self.__dir = value
@property
def spaces(self): return self.__spaces
@spaces.setter
def spaces(self, value):
if value == None or len(value) < 1:
raise pkex.BasePyKatException('Must be a list of space names')
self.__spaces = value
@staticmethod
def parseFinesseText(text):
values = text.split()
if len(values) > 3:
return gouy(str(values[1]), str(values[2]), values[3:])
else:
raise pkex.BasePyKatException('Gouy detector code "{0}" is not a valid FINESSE command'.format(text))
def getFinesseText(self) :
rtn = []
rtn.append("gouy {name} {dir} {spaces}".format(name=self.name, dir=str(self.direction), spaces=" ".join(self.spaces)))
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
class bp(Detector):
acceptedParameters = ['w', 'w0', 'z', 'zr', 'g', 'r', 'q']
def __init__(self, name, direction, parameter, node, alternate_beam=False):
Detector.__init__(self, name, node)
self.parameter = parameter
self.direction = direction
self.alternate_beam = alternate_beam
@property
def direction(self): return self.__dir
@direction.setter
def direction(self, value):
if value == None or (value != 'x' and value != 'y'):
raise pkex.BasePyKatException('Direction must be either x or y')
self.__dir = value
@property
def parameter(self): return self.__param
@parameter.setter
def parameter(self, value):
if value == None or (value not in self.acceptedParameters) :
raise pkex.BasePyKatException('Parameter must be one of: %s'%(", ".join(self.acceptedParameters)))
self.__param = value
@staticmethod
def parseFinesseText(text):
values = text.split()
node=values[-1]
alt_beam = node[-1] == '*'
if len(values) > 3:
return bp(str(values[1]), str(values[2]), str(values[3]), str(values[4]), alternate_beam=alt_beam)
else:
raise pkex.BasePyKatException('Gouy detector code "{0}" is not a valid FINESSE command'.format(text))
def getFinesseText(self) :
rtn = []
if self.alternate_beam:
alt = "*"
else:
alt = ""
rtn.append("bp {name} {dir} {param} {node}{alt}".format(name=self.name, dir=str(self.direction), param=self.parameter, node=self.node.name, alt=alt))
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
class pd(Detector):
def __init__(self, name, num_demods, node_name, senstype=None, alternate_beam=False, pdtype=None, **kwargs):
......
......@@ -601,6 +601,10 @@ class kat(object):
obj = pykat.components.modulator.parseFinesseText(line)
elif(first[0:2] == "ad"):
obj = pykat.detectors.ad.parseFinesseText(line)
elif(first[0:2] == "bp"):
obj = pykat.detectors.bp.parseFinesseText(line)
elif(first[0:4] == "gouy"):
obj = pykat.detectors.gouy.parseFinesseText(line)
elif(first[0:2] == "pd" and first != "pdtype"):
obj = pykat.detectors.pd.parseFinesseText(line)
elif(first == "qshot" or first == "qshotS" or first == "qshotN"):
......
......@@ -230,7 +230,147 @@ class NodeNetwork(object):
def __contains__(self, value):
return value in self.__nodes
def __nodeSearch(self, fnode, currcomp, branches, tnode):
if fnode == tnode:
branches[-1][0] = True
branches[-1][1] = True
return True # Hurrah, we have found a path to the node
elif fnode.isDump:
branches[-1][0] = True
return False # if the current node is a dump, we need to check another branch
nextnode = None
if isinstance(currcomp, pykat.components.beamSplitter):
# if we get to a beamsplitter then we need to
# create new branches to search: the rfelected
# and transmitted
# set this branch as searched
branches[-1][0] = True
# add two new ones
if fnode == currcomp.nodes[0]:
rn = currcomp.nodes[1]
tn = currcomp.nodes[2]
elif fnode == currcomp.nodes[1]:
rn = currcomp.nodes[0]
tn = currcomp.nodes[3]
elif fnode == currcomp.nodes[2]:
rn = currcomp.nodes[3]
tn = currcomp.nodes[0]
elif fnode == currcomp.nodes[3]:
rn = currcomp.nodes[2]
tn = currcomp.nodes[1]
else:
raise exceptions.ValueError("Node not attached in path find to BS")
nextcomp = None
if tn.components[0] == currcomp:
nextcomp = tn.components[1]
elif tn.components[1] == currcomp:
nextcomp = tn.components[0]
if nextcomp != None:
branches.append([False, False, tn, nextcomp, []])
if rn.components[0] == currcomp:
nextcomp = rn.components[1]
elif rn.components[1] == currcomp:
nextcomp = rn.components[0]
if nextcomp != None:
branches.append([False, False, rn, nextcomp, []])
branches[-1][-1].append(currcomp)
return False
elif isinstance(currcomp, pykat.components.isolator):
print "isol"
elif isinstance(currcomp, pykat.components.laser):
# if we are at a laser then we can't go any further
# and it isn;t this node as we checked before
branches[-1][0] = True
return False
elif len(currcomp.nodes) == 2:
if currcomp.nodes[0] == fnode:
nextnode = currcomp.nodes[1]
elif currcomp.nodes[1] == fnode:
nextnode = currcomp.nodes[0]
else:
raise pkex.BasePyKatException("Unexpeceted condition")
else:
raise pkex.BasePyKatException("Did not handle component {0} correctly, has more or less than 2 nodes.".format(currcomp))
if nextnode == None:
branches[-1][0] = True
return False
elif nextnode == tnode:
branches[-1][0] = True
branches[-1][1] = True
branches[-1][-1].append(currcomp)
return True
else:
# Now we have the next node, we need the next component
if nextnode.components[0] == currcomp:
nextcomp = nextnode.components[1]
elif nextnode.components[1] == currcomp:
nextcomp = nextnode.components[0]
else:
raise pkex.BasePyKatException("Unexpeceted condition")
if nextcomp == None:
branches[-1][0] = True
return False
branches[-1][-1].append(currcomp)
return self.__nodeSearch(nextnode, nextcomp, branches, tnode)
def getComponentsBetween(self, from_node, to_node):
if from_node not in self.__nodes:
raise pkex.BasePyKatException("Node {0} cannot be found in this kat object".format(from_node))
if to_node not in self.__nodes:
raise pkex.BasePyKatException("Node {0} cannot be found in this kat object".format(to_node))
branches = []
fn = self.__nodes[from_node]
tn = self.__nodes[to_node]
branches.append([False, False, fn, fn.components[1], []])
branches.append([False, False, fn, fn.components[0], []])
while len(branches) > 0 and branches[-1][1] != True:
while branches[-1][0] == False:
branch = branches[-1]
if not self.__nodeSearch(branch[2], branch[3], branches, tn):
if len(branches) > 0 and branches[-1][0] != False:
branches.pop()
if branches[-1][1] != True:
while len(branches) > 0 and branches[-1][0] == True:
branches.pop()
comps = []
if len(branches) > 0 and branches[-1][0] == True and branches[-1][1] == True:
# select the branches that form the path from node to node
br = [b for b in branches if b[0] == True]
for b in br:
comps.extend(b[-1])
return comps
class Node(object):
......@@ -243,9 +383,13 @@ class Node(object):
self.__q_y = None
self.__q_comp = None
self.__id = id
self._isDump = False
def __str__(self): return self.__name
@property
def isDump(self): return self._isDump
@property
def id(self): return self.__id
......@@ -350,13 +494,14 @@ class Node(object):
@property
def name(self): return self.__name
class DumpNode(Node):
__total_dump_node_id = 0
def __init__(self):
DumpNode.__total_dump_node_id -= 1
Node.__init__(self, 'dump', None, DumpNode.__total_dump_node_id)
self._isDump = True
import pykat
import pykat.exceptions as pkex
import copy
import numpy as np
import pylab
def plot_beam_trace(_kat, from_node, to_node):
if _kat == None:
raise pkex.BasePyKatException('kat object in None')
kat = copy.deepcopy(_kat)
components = kat.nodes.getComponentsBetween(from_node, to_node)
nodes = []
for cn in range(len(components)):
for n in components[cn].nodes:
cs = np.array(n.components)
if cn < len(components)-1 and components[cn] in cs and components[cn+1] in cs:
nodes.append(n)
break
elif cn == len(components)-1 and components[cn-1] not in cs and components[cn] in cs:
nodes.append(n)
break
v = [c for c in zip(components, nodes) if isinstance(c[0], pykat.components.space)]
spaces = [d[0] for d in v]
nodes2 = [d[1] for d in v]
print [n.name for n in spaces ]
pylab.figure()
if len(spaces) > 0:
print "Plotting beam along spaces", ", ".join([s.name for s in spaces])
for d in kat.detectors.values():
d.remove()
if hasattr(kat, "xaxis"):
kat.xaxis.remove()
if hasattr(kat, "x2axis"):
kat.x2axis.remove()
if hasattr(kat, "x3axis"):
kat.x3axis.remove()
kat.noxaxis = False
kat.maxtem = 0
currL = 0
L = []
wx = []
gx = []
wy = []
gy = []
for n in range(len(spaces)):
s = spaces[n]
Lmax = s.L
N = 100
node = None
cmds = """
gouy gx1 x {spaces}
bp bpx x w {node}*
gouy gy1 y {spaces}
bp bpy y w {node}*
xaxis {space} L lin 0 {Lmax} {N}
""".format(space=s.name, Lmax=Lmax, N=int(N), spaces=" ".join([s.name for s in spaces[0:n+1]]), node=nodes2[n])
k = copy.deepcopy(kat)
k.parseCommands(cmds)
k.verbose = False
out = k.run()
pylab.subplot(2,1,1)
L.extend(currL + out.x)
wx.extend(out['bpx'])
wy.extend(out['bpy'])
gx.extend(out['gx1'])
gy.extend(out['gy1'])
currL += Lmax
pylab.subplot(2,1,1)
wx = np.array(wx)/1e-2
wy = np.array(wy)/1e-2
pylab.plot(L, wx, 'b', L, wy, 'r', L, -wx, 'b', L, -wy, 'r')
pylab.title("Beam size between %s and %s" % (from_node, to_node))
pylab.ylabel("Beam size [cm]")
pylab.xlabel("Distance from %s to %s [m]" % (from_node, to_node))
pylab.xlim(min(L), max(L))
pylab.subplot(2,1,2)
pylab.plot(L, gx, 'b', L, gy, 'r')
pylab.title("Gouy phase accumulation between %s and %s" % (from_node, to_node))
pylab.ylabel("Phase accumulation [deg]")
pylab.xlabel("Distance [m]")
pylab.xlim(min(L), max(L))
pylab.legend(['x','y'], 0)
pylab.tight_layout()
pylab.show()
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment