Commit c3ec8636 authored by Daniel Brown's avatar Daniel Brown
Browse files

Adding in more parsing for finesse commands. Can no specify a chunk of finesse...

Adding in more parsing for finesse commands. Can no specify a chunk of finesse codee. Various other fixes included too. Currently GUI isn't working.
parent 7cbd9cb7
......@@ -4,7 +4,7 @@ m m1 0.5 0.5 0 n2 n3
s s2 10 1 n3 n4
m m2 0.5 0.5 0 n4 dump
pd PD1 n
pd PD1 n2
xaxis m1 phi lin 0 360 1000
from pykat import finesse
from pykat.commands import xaxis
import pylab as pl
import numpy as np
code = """
l l1 1 0 0 n1
s s1 10 1 n1 n2
m m1 1 0 0 n2 dump
gauss g1 m1 n2 1e-3 0
pd refl n2
xaxis m1 r_ap lin 0.1e-3 2e-3 10
"""
kat = finesse.kat(kat_code = code)
maxtem = np.arange(0, 3, 2)
for tem in maxtem:
print "Calculating maxtem ",tem,"..."
kat.maxtem = tem
r = kat.run()
pl.plot(r.x/1e-3, r.y, label="maxtem={0}".format(tem))
pl.ylabel("Reflected Power [W]")
pl.xlabel("Mirror aperture [mm]")
pl.legend()
pl.show()
\ No newline at end of file
import sys
sys.path.append(".")
from pykat import finesse, profiling
import numpy as np
from pykat import finesse
from pykat.commands import xaxis
import pylab as pl
kat = finesse.kat()
#kat.load("D:\\finesse\\test\\kat_test\\physics\\mirror_astig_tilt_all_BH.kat")
kat.load('parse.kat')
kat.getPerformanceData = True
code = """
l l1 1 0 0 n1
s s1 10 1 n1 n2
m m1 0.5 0.5 0 n2 n3
s s2 10 1 n3 n4
m m2 0.5 0.5 0 n4 dump
ad ad1 0 n2
"""
kat = finesse.kat(kat_code = code)
[run, perfdata] = kat.run(printout=0,printerr=0)
kat.add(xaxis("lin", [0, 360], kat.m2, kat.m2.phi, 1000))
l,t,fig = profiling.plotReducedPerformanceData(perfdata)
r = kat.run(printerr=1)
fig.savefig("Timing.png",pad_inches=0.1, bbox_inches='tight')
fig.show()
pl.plot(r.x, r.y)
pl.show()
\ No newline at end of file
import sys
sys.path.append("../")
from pykat import finesse
from pykat.detectors import *
from pykat.components import *
from pykat.commands import *
from pykat.structs import *
#from pykat.plotting import *
import numpy as np
import pylab as pl
kat = finesse.kat()
code = """
l l1 1 0 0 n1
s s1 10 1 n1 n2
m m1 0.5 0.5 0 n2 n3
s s2 10 1 n3 n4
m m2 0.5 0.5 0 n4 n5
s s3 10 1 n5 n6
"""
kat = finesse.kat(kat_code=code)
laser(kat,'l1','n1',1)
space(kat,'s1','n1','n2',1)
kat.add(cavity('cav1','m1','n3','m2','n4'))
mirror(kat,'m1','n2','n3',R=0.8,T=0.2)
space(kat,'s2','n3','n4',L=1)
mirror(kat,'m2','n4','n5',R=0.7,T=0.3)
cavity(kat, 'cav1','m1','n3','m2','n4')
space(kat,'s3','n5','n6',L=1)
kat.add(photodiode('pd_cav','n4'))
kat.add(photodiode('pd_ref','n2'))
kat.add(photodiode('pd_trs','n5'))
photodiode(kat,'pd_cav','n4')
photodiode(kat,'pd_ref','n2')
photodiode(kat,'pd_trs','n5')
kat.add(xaxis(Scale.linear, [0, 360], kat.m2, kat.m2.phi, 100))
kat.m1.Rcx = -1000.0
kat.m1.Rcy = -1000.0
kat.m2.Rcx = 1000.0
kat.m2.Rcy = 1000.0
xaxis(kat, Scale.linear, [0,360], kat.m2, kat.m2.phi, 1000)
kat.maxtem = 0
run = kat.run(printout=0,printerr=0)
#pl.figure()
#pl.ion()
#pl.plot(run.x,run.y)
#pl.xlabel(run.xlabel)
#pl.ylabel("Intensity [W]")
#pl.legend(run.ylabels)
#pl.show()
kat.m1.R = 0.5
kat.m1.T = 0.5
kat.pd_cav.enabled = False
run = kat.run(printout=0,printerr=0)
#pl.figure()
#pl.plot(run.x,run.y)
#pl.xlabel(run.xlabel)
#pl.ylabel("Intensity [W]")
#pl.legend(run.ylabels)
#pl.show()
kat.openGUI()
pl.figure()
pl.plot(run.x,run.y)
pl.xlabel(run.xlabel)
pl.ylabel("Intensity [W]")
pl.legend(run.ylabels)
pl.show()
__all__ = ['finesse', 'components', 'detectors', 'commands']
#__all__ = ['finesse', 'components', 'detectors', 'commands']
import finesse
import components
import detectors
import commands
......@@ -15,24 +15,27 @@ class Command(object):
""" Base class for individual finesse optical components """
raise NotImplementedError("This function is not implemented")
def _on_kat_add(self, kat):
"""
Called when this component has been added to a kat object
"""
self._kat = kat
class cavity(Command):
def __init__(self, kat, name, c1, n1, c2, n2):
def __init__(self, name, c1, n1, c2, n2):
self.__name = name
self.__c1 = c1
self.__c2 = c2
self.__n1 = n1
self.__n2 = n2
kat.add(self)
def getFinesseText(self):
return 'cav {0} {1} {2} {3} {4}'.format(
self.__name, self.__c1, self.__n1, self.__c2, self.__n2);
return 'cav {0} {1} {2} {3} {4}'.format(self.__name, self.__c1, self.__n1, self.__c2, self.__n2);
class xaxis(Command):
def __init__(self, kat, scale, limits, comp, param, steps):
def __init__(self, scale, limits, comp, param, steps):
if scale == "lin":
scale = Scale.linear
......@@ -57,22 +60,28 @@ class xaxis(Command):
self.steps = steps
if not isinstance(comp, Component):
raise exceptions.ValueError("comp is not a Component")
# if entered component is a string then just store and use that
if isinstance(comp, str):
self.__comp = comp
elif not isinstance(comp, Component):
raise exceptions.ValueError("{0} has not been added".format(comp))
else:
self.__comp = comp
if not isinstance(param, Param) :
if isinstance(param, str):
self.__param = param
elif not isinstance(param, Param) :
raise exceptions.ValueError("param argument is not of type Param")
self._param = param
kat.add(self)
else:
self.__param = param
def getFinesseText(self):
# store either the component name of the string provided
comp_name = self.__comp.name if isinstance(self.__comp, Component) else self.__comp
param_name = self.__param.name if isinstance(self.__param, Param) else self.__param
return 'xaxis {0} {1} {2} {3} {4} {5}'.format(
self.__comp.name, self._param.name, self.scale,
comp_name, param_name, self.scale,
min(self.limits), max(self.limits), self.steps);
\ No newline at end of file
......@@ -7,24 +7,37 @@ Created on Mon Jan 28 11:10:01 2013
import exceptions
import pykat.gui.resources
import pykat
import inspect
import pykat.gui.graphics
from pykat.gui.graphics import *
#from pykat.gui.graphics import *
from pykat.node_network import *
from PyQt4.QtGui import *
from PyQt4.Qt import *
#from PyQt4.QtGui import *
#from PyQt4.Qt import *
class Component(object) :
def __init__(self, name, kat):
def __init__(self, name):
self.__name = name
self._svgItem = None
self.__nodes = []
self._requested_node_names = []
self._kat = None
#if not isinstance(kat,pykat.finesse.kat):
# raise exceptions.ValueError("kat argument is not a pykat.finesse.kat object")
#kat.add(self)
def _on_kat_add(self, kat):
"""
Called when this component has been added to a kat object
"""
self._kat = kat
if not isinstance(kat,pykat.finesse.kat):
raise exceptions.ValueError("kat argument is not a pykat.finesse.kat object")
for node_name in self._requested_node_names:
self._addNode(node_name)
kat.add(self)
@staticmethod
def parseFinesseText(text):
raise NotImplementedError("This function is not implemented")
def getFinesseText(self):
""" Base class for individual finesse optical components """
......@@ -67,12 +80,12 @@ class Param(float):
name = property(lambda self: self.__name)
class mirror(Component):
def __init__(self,kat,name,node1,node2,R=0,T=0,phi=0,Rcx=0,Rcy=0,xbeta=0,ybeta=0):
def __init__(self,name,node1,node2,R=0,T=0,phi=0,Rcx=0,Rcy=0,xbeta=0,ybeta=0):
Component.__init__(self,name,kat)
Component.__init__(self,name)
self.node1 = self._addNode(node1)
self.node2 = self._addNode(node2)
self._requested_node_names.append(node1)
self._requested_node_names.append(node2)
self.__R = R
self.__T = T
......@@ -129,11 +142,30 @@ class mirror(Component):
self.Rcx = value
self.Rcy = value
@staticmethod
def parseFinesseText(text):
values = text.split(" ")
if values[0] != "m":
raise exceptions.RuntimeError("'{0}' not a valid Finesse mirror command".format(text))
values.pop(0) # remove initial value
if len(values) != 6:
raise exceptions.RuntimeError("Mirror Finesse code format incorrect '{0}'".format(text))
return mirror(values[0], values[4], values[5], R=values[1], T=values[2], phi=values[3])
def getFinesseText(self):
rtn = []
nodes = self.getNodes()
if len(nodes) != 2:
raise exceptions.RuntimeError("Not enough nodes for mirror")
rtn.append('m {0} {1} {2} {3} {4} {5}'.format(
self.name, self.__R, self.__T, self.__phi,
self.node1.name, self.node2.name))
nodes[0].name, nodes[1].name))
if self.Rcx != 0: rtn.append("attr {0} Rcx {1}".format(self.name,self.__Rcx))
if self.Rcy != 0: rtn.append("attr {0} Rcy {1}".format(self.name,self.__Rcy))
......@@ -144,17 +176,18 @@ class mirror(Component):
def getQGraphicsItem(self):
if self._svgItem == None:
nodes = self.getNodes()
self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/mirror_flat.svg",self
,[(-4,15,self.node1),(14,15,self.node2)])
,[(-4,15,self.nodes[0]),(14,15,self.nodes[1])])
return self._svgItem
class space(Component):
def __init__(self,kat , name, node1, node2, L=0, n=1):
Component.__init__(self,name,kat)
def __init__(self, name, node1, node2, L=0, n=1):
Component.__init__(self,name,)
self.node1 = self._addNode(node1)
self.node2 = self._addNode(node2)
self._requested_node_names.append(node1)
self._requested_node_names.append(node2)
self.__L = L
self.__n = n
......@@ -169,11 +202,29 @@ class space(Component):
@n.setter
def n(self,value): self.__n = value
@staticmethod
def parseFinesseText(text):
values = text.split(" ")
if values[0] != "s":
raise exceptions.RuntimeError("'{0}' not a valid Finesse space command".format(text))
values.pop(0) # remove initial value
if len(values) == 5:
return space(values[0],values[3],values[4],L=values[1],n=values[2])
elif len(values) == 4:
return space(values[0],values[2],values[3],L=values[1])
else:
raise exceptions.RuntimeError("Space Finesse code format incorrect '{0}'".format(text))
def getFinesseText(self):
nodes = self.getNodes()
if self.__n == 1:
return 's {0} {1} {2} {3}'.format(self.name, self.__L, self.node1.name, self.node2.name)
return 's {0} {1} {2} {3}'.format(self.name, self.__L, nodes[0].name, nodes[1].name)
else:
return 's {0} {1} {2} {3} {4}'.format(self.name, self.__L, self.__n, self.node1.name, self.node2.name)
return 's {0} {1} {2} {3} {4}'.format(self.name, self.__L, self.__n, nodes[0].name, nodes[1].name)
def getQGraphicsItem(self):
if self._QItem == None:
......@@ -197,10 +248,10 @@ class space(Component):
class laser(Component):
def __init__(self,kat,name,node,P=1,f_offset=0,phase=0):
Component.__init__(self,name,kat)
def __init__(self,name,node,P=1,f_offset=0,phase=0):
Component.__init__(self,name)
self.node = self._addNode(node)
self._requested_node_names.append(node)
self.__power = P
self.__f_offset = f_offset
......@@ -221,16 +272,31 @@ class laser(Component):
@phase.setter
def phase(self,value): self.__phase = value
@staticmethod
def parseFinesseText(text):
values = text.split(" ")
if values[0] != "l":
raise exceptions.RuntimeError("'{0}' not a valid Finesse laser command".format(text))
values.pop(0) # remove initial value
if len(values) == 5:
return laser(values[0],values[4],P=values[1],f_offset=values[2],phase=values[3])
elif len(values) == 4:
return laser(values[0],values[3],P=values[1],f_offset=values[2], phase=0)
else:
raise exceptions.RuntimeError("Laser Finesse code format incorrect '{0}'".format(text))
def getFinesseText(self):
if self.__phase == 0 :
return 'l {0} {1} {2} {3}'.format(self.name, self.__power, self.__f_offset, self.node.name)
else :
return 'l {0} {1} {2} {4} {3}'.format(self.name, self.__power, self.__f_offset, self.__phase, self.node.name)
nodes = self.getNodes()
return 'l {0} {1} {2} {3} {4}'.format(self.name, self.__power, self.__f_offset, self.__phase, nodes[0].name)
def getQGraphicsItem(self):
if self._svgItem == None:
self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/laser.svg",
self,[(65,25,self.node)])
self,[(65,25,nodes[0])])
return self._svgItem
......@@ -13,17 +13,26 @@ from pykat.gui.graphics import *
from pykat.node_network import *
class Detector(object) :
def __init__(self, name,node,kat):
def __init__(self, name,node):
self.__name = name
self._svgItem = None
self._kat = kat
self._kat = None
self.noplot = False
self.enabled = True
kat.add(self)
if node.find('*'):
self._alternate_beam = True
node.replace('*','')
self.__requested_node = node
self.__node = kat.nodes.createNode(node)
self.__node.connect(self)
def _on_kat_add(self, kat):
self._node = kat.nodes.createNode(self.__requested_node)
#self.__node.connect(self)
@staticmethod
def parseFinesseText(text):
raise NotImplementedError("This function is not implemented")
def getFinesseText(self):
""" Base class for individual finesse optical components """
......@@ -41,24 +50,18 @@ class Detector(object) :
name = property(__getname)
class photodiode(Detector):
def __init__(self,kat,name,node) :
Detector.__init__(self,name,node,kat)
if node.find('*'):
self._alternate_beam = True
node.replace('*','')
self.__node = kat.nodes.createNode(node)
@staticmethod
def parseFinesseText(text):
raise NotImplementedError("This function is not implemented")
def getFinesseText(self) :
if self.enabled:
rtn = []
if self._alternate_beam:
rtn.append("pd {0} {1}".format(self.name, self.__node.name))
rtn.append("pd {0} {1}".format(self.name, self._node.name))
else:
rtn.append("pd {0} {1}*".format(self.name, self.__node.name))
rtn.append("pd {0} {1}*".format(self.name, self._node.name))
if self.noplot:
rtn.append("noplot {0}".format(self.name))
......
......@@ -31,6 +31,7 @@ import tempfile
import numpy as np
import datetime
import pickle
import pykat
from pykat.node_network import NodeNetwork
from pykat.detectors import Detector
......@@ -48,6 +49,13 @@ class MissingFinesse(Exception) :
"or you do not have the permissions to run it." \
.format(os.environ.get('FINESSE_DIR'))
class FinesseError(Exception) :
def __init__(self, err, kat):
self.__err = err
self.__kat = kat
def __str__(self):
return "Finesse returned an error running {1}: {0}".format(self.__err, self.__kat)
class katRun(object):
def __init__(self):
......@@ -75,7 +83,7 @@ class katRun(object):
class kat(object):
def __init__(self, katexe=""):
def __init__(self, kat_file=None, kat_code=None, katexe=""):
self.scene = None # scene object for GUI
self.__components = {} # dictionary of optical components
......@@ -92,6 +100,15 @@ class kat(object):
self.__noxaxis = None
self.__time_code = None
if kat_code != None and kat_file != None:
raise exceptions.RuntimeError("Specify either a Kat file or some Kat code, not both.")
if kat_code != None:
self.parseCommands(kat_code)
if kat_file != None:
self.loadKatFile(kat_file)
@property
def maxtem(self): return self.__maxtem
@maxtem.setter
......@@ -112,15 +129,24 @@ class kat(object):
@noxaxis.setter
def noxaxis(self,value): self.__noxaxis = bool(value)
def load(self, katfile):
"""
Loads the kat file specified which can then be run
"""
def loadKatFile(self, katfile):
with open(katfile) as f:
for lines in f.readlines():
self.__extra_lines.append(lines)
parseCommands(f.readlines())
def parseCommands(self, commands):
for line in commands.split("\n"):
if len(line.strip()) > 0:
first = line.split(" ",1)[0]
if(first == "m"):
self.add(pykat.components.mirror.parseFinesseText(line))
elif(first == "s"):
self.add(pykat.components.space.parseFinesseText(line))
elif(first == "l"):
self.add(pykat.components.laser.parseFinesseText(line))
else:
print "Could not parse `{0}`".format(line)
self.__extra_lines.append(line + "\n")
def run(self, printout=1, printerr=1, save_output=False, save_kat=False,kat_name=None) :
"""
......@@ -128,7 +154,7 @@ class kat(object):
It returns a katRun object which is populated with the various
data from the simulation run.
"""
try:
r = katRun()
r.katScript = "".join(self.generateKatScript())
......@@ -162,8 +188,10 @@ class kat(object):
kat_exec = "{0} {1} {2}".format(kat_exec, flags, katfile.name)
p=subprocess.Popen(kat_exec, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
err = ""
for line in iter(p.stderr.readline, ""):
err += line
vals = line.split("-")
if len(vals) == 2:
......@@ -174,7 +202,9 @@ class kat(object):
sys.stdout.write("\r{0} {1}%".format(action, prc))