Skip to content
Snippets Groups Projects
Commit 223ef74d authored by Daniel Brown's avatar Daniel Brown
Browse files

Large amount of changes to the param object which now include being able to...

Large amount of changes to the param object which now include being able to put and set parameters and commands. Also adding the modulator component.
parent 056dd5ed
No related branches found
No related tags found
No related merge requests found
class Param(float): import abc
def __new__(self,name,value): import pykat.exceptions as pkex
return float.__new__(self,value)
def __init__(self,name,value): class puttable(object):
self.__name = name """
Objects that inherit this should be able to have something `put` to it.
Essentially this means you could write Finesse commands like
name = property(lambda self: self.__name) put this parameter value
"""
__metaclass__ = abc.ABCMeta
def __init__(self, component_name, parameter_name):
self._parameter_name = parameter_name
self._component_name = component_name
self._putter = None
def put(self, var):
if not isinstance(var, putter):
raise pkex.BasePyKatException("var was not something that can be `put` as a value")
if self._putter != None:
self._putter.put_count -= 1
self._putter = var
self._putter.put_count += 1
def getPutFinesseText(self):
rtn = []
# if something is being put to this
if self._putter != None:
rtn.append("put {comp} {param} ${value}".format(comp=self._component_name, param=self._parameter_name, value=self._putter.put_name()))
return rtn
class putter(object):
"""
If an object can be put to something that is puttable it should inherit this
object.
"""
__metaclass__ = abc.ABCMeta
def __init__(self, put_name):
self._put_name = put_name
self.put_count = 0
def put_name(self): return self._put_name
class Beer(object):
def __init__(self, temp): class Param(puttable, putter):
self.__T = temp def __init__(self, name, owner, value):
self._name = name
self._owner = owner
self._value = value
putter.__init__(self,"var_{0}_{1}".format(owner.name, name))
puttable.__init__(self, owner.name, name)
@property @property
def temp(self): def name(self): return self._name
return Param('Beer Temperature', self.__T)
@property
def value(self): return self._value
@value.setter
def value(self, value):
self._value = value
def __float__(self): return self.value
def getFinesseText(self):
rtn = []
rtn.extend(self.getPutFinesseText())
# if this parameter is being put somewhere then we need to
# set it as a variable
if self.put_count > 0:
rtn.append("set {put_name} {comp} {param}".format(put_name=self.put_name(), comp=self._owner.name, param=self.name))
return rtn
def __mul__(self, a):
return float(self) * a
@temp.setter def __imul__(self, a):
def temp(self,value): return self.value * float(a)
self.__T = float(value)
__rmul__ = __mul__
b = Beer(100) def __add__(self, a):
return self.value + flota(a)
print b.temp.name, b.temp.__class__ def __iadd__(self, a):
return self.value + float(a)
__radd__ = __add__
def __sub__(self, a):
return self.value - float(a)
def __isub__(self, a):
return self.value - float(a)
__rsub__ = __sub__
def __div__(self, a):
return self.value / float(a)
def __idiv__(self, a):
return self.value / complex(a)
def __pow__(self, q):
return self.value**q
def __neg__(self):
return -self.value
def __eq__(self, q):
return float(q) == self.value
class Beer(object):
def __init__(self, temp, name):
self._name = name
self._T = Param('T', self, temp)
@property
def name(self): return self._name
@property
def T(self): return self._T
print b.temp * 4.5 @T.setter
def T(self,value): self._T.value = float(value)
print b.temp.name, b.temp.__class__
b.temp = 101 b = Beer(1,"b")
c = Beer(2,"c")
print b.temp.name, b.temp.__class__ c.T.put(b.T)
print b.temp print c.T.getFinesseText()
\ No newline at end of file print b.T.getFinesseText()
\ No newline at end of file
from pykat import finesse
from pykat.detectors import *
from pykat.components import *
from pykat.commands import *
from pykat.structs import *
import numpy as np
import pylab as pl
code = """
l l1 1 0 0 n1
s s1 10 1 n1 n2
mod eom 10 0.1 1 am 0 n2 n3
"""
kat = finesse.kat()
kat.parseCommands(code)
kat.add(photodiode('pd_ref','n3', num_demods=1, demods=[10,0]))
kat.add(xaxis("lin", [0, 1000], "pd_ref", "f1", 100))
out = kat.run(printout=0, printerr=0)
pl.figure()
pl.plot(out.x, out["pd_ref"])
pl.xlabel(out.xlabel)
pl.ylabel("Intensity [W]")
pl.legend(out.ylabels)
pl.show()
...@@ -9,6 +9,7 @@ from numpy import min,max ...@@ -9,6 +9,7 @@ from numpy import min,max
import exceptions import exceptions
from components import * from components import *
from structs import * from structs import *
from pykat.param import Param, putter
class Command(object): class Command(object):
def __init__(self): def __init__(self):
...@@ -47,39 +48,14 @@ class gauss(object): ...@@ -47,39 +48,14 @@ class gauss(object):
if not values[0].startswith("gauss"): if not values[0].startswith("gauss"):
raise exceptions.RuntimeError("'{0}' not a valid Finesse gauss command".format(text)) raise exceptions.RuntimeError("'{0}' not a valid Finesse gauss command".format(text))
class attr():
@staticmethod
def parseFinesseText(text, kat):
values = text.split(" ")
if values[0] != "attr":
raise exceptions.RuntimeError("'{0}' not a valid Finesse attr command".format(text))
values.pop(0) # remove initial value
if len(values) < 3:
raise exceptions.RuntimeError("attr Finesse code format incorrect '{0}'".format(text))
comp = None
comp_name = values[0]
values.pop(0)
for c in kat.getComponents():
if c.name == comp_name:
comp = c
break
if comp == None:
raise
# can list multiple attributes per command
class xaxis(Command): class xaxis(Command):
def __init__(self, scale, limits, comp, param, steps, axis_type="xaxis"): def __init__(self, scale, limits, comp, param, steps, axis_type="xaxis"):
self._axis_type = axis_type self._axis_type = axis_type
self.x = putter("x1")
self.mx = putter("mx1")
if scale == "lin": if scale == "lin":
scale = Scale.linear scale = Scale.linear
elif scale == "log": elif scale == "log":
...@@ -146,6 +122,8 @@ class xaxis(Command): ...@@ -146,6 +122,8 @@ class xaxis(Command):
class x2axis(xaxis): class x2axis(xaxis):
def __init__(self, scale, limits, comp, param, steps): def __init__(self, scale, limits, comp, param, steps):
xaxis.__init__(self, scale, limits, comp, param, steps, axis_type="x2axis") xaxis.__init__(self, scale, limits, comp, param, steps, axis_type="x2axis")
self.x = putter("x2")
self.mx = putter("mx2")
@staticmethod @staticmethod
def parseFinesseText(text): def parseFinesseText(text):
......
...@@ -15,6 +15,7 @@ import pykat.gui.resources ...@@ -15,6 +15,7 @@ import pykat.gui.resources
import pykat.gui.graphics import pykat.gui.graphics
from pykat.gui.graphics import * from pykat.gui.graphics import *
from pykat.SIfloat import * from pykat.SIfloat import *
from pykat.param import Param, AttrParam
next_component_id = 1 next_component_id = 1
...@@ -58,6 +59,7 @@ class Component(object): ...@@ -58,6 +59,7 @@ class Component(object):
self._requested_node_names = [] self._requested_node_names = []
self._kat = None self._kat = None
self.tag = None self.tag = None
self._params = []
# store a unique ID for this component # store a unique ID for this component
global next_component_id global next_component_id
...@@ -70,6 +72,9 @@ class Component(object): ...@@ -70,6 +72,9 @@ class Component(object):
cls = type(self) cls = type(self)
self.__class__ = type(cls.__name__, (cls,), {}) self.__class__ = type(cls.__name__, (cls,), {})
def _register_param(self, param):
self._params.append(param)
def _on_kat_add(self, kat): def _on_kat_add(self, kat):
""" """
Called when this component has been added to a kat object. Called when this component has been added to a kat object.
...@@ -145,87 +150,66 @@ class Component(object): ...@@ -145,87 +150,66 @@ class Component(object):
def __str__(self): return self.name def __str__(self): return self.name
class Param(float):
def __new__(self,name,value):
return float.__new__(self,SIfloat(value))
def __init__(self,name,value):
self.__name = name
name = property(lambda self: self.__name)
class AbstractMirrorComponent(Component): class AbstractMirrorComponent(Component):
__metaclass__ = abc.ABCMeta __metaclass__ = abc.ABCMeta
def __init__(self, name, R=0, T=0, phi=0, Rcx=0, Rcy=0, xbeta=0, ybeta=0, mass=0, r_ap=0): def __init__(self, name, R=0, T=0, phi=0, Rcx=0, Rcy=0, xbeta=0, ybeta=0, mass=0, r_ap=0):
super(AbstractMirrorComponent, self).__init__(name) super(AbstractMirrorComponent, self).__init__(name)
self.__R = SIfloat(R) self.__R = Param("R", self, SIfloat(R))
self.__T = SIfloat(T) self.__T = Param("T", self, SIfloat(T))
self.__phi = SIfloat(phi) self.__phi = Param("phi", self, SIfloat(phi))
self.__Rcx = SIfloat(Rcx) self.__Rcx = AttrParam("Rcx", self, SIfloat(Rcx))
self.__Rcy = SIfloat(Rcy) self.__Rcy = AttrParam("Rcy", self, SIfloat(Rcy))
self.__xbeta = SIfloat(xbeta) self.__xbeta = AttrParam("xbeta", self, SIfloat(xbeta))
self.__ybeta = SIfloat(ybeta) self.__ybeta = AttrParam("ybeta", self, SIfloat(ybeta))
self.__mass = SIfloat(mass) self.__mass = AttrParam("mass", self, SIfloat(mass))
self.__r_ap = SIfloat(r_ap) self.__r_ap = AttrParam("r_ap", self, SIfloat(r_ap))
def getAttributeText(self):
rtn = []
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))
if self.xbeta != 0: rtn.append("attr {0} xbeta {1}".format(self.name,self.__xbeta))
if self.ybeta != 0: rtn.append("attr {0} ybeta {1}".format(self.name,self.__ybeta))
if self.mass != 0: rtn.append("attr {0} mass {1}".format(self.name,self.__mass))
if self.r_ap != 0: rtn.append("attr {0} r_ap {1}".format(self.name,self.__r_ap))
return rtn
@property @property
def r_ap(self): return Param('r_ap', self.__r_ap) def r_ap(self): return self.__r_ap
@r_ap.setter @r_ap.setter
def r_ap(self,value): self.__aperture = SIfloat(value) def r_ap(self,value): self.__r_ap.value = SIfloat(value)
@property @property
def mass(self): return Param('mass', self.__mass) def mass(self): return self.__mass
@mass.setter @mass.setter
def mass(self,value): self.__mass = SIfloat(value) def mass(self,value): self.__mass.value = SIfloat(value)
@property @property
def R(self): return Param('R', self.__R) def R(self): return self.__R
@R.setter @R.setter
def R(self,value): self.__R = SIfloat(value) def R(self,value): self.__R.value = SIfloat(value)
@property @property
def T(self): return Param('T', self.__T) def T(self): return self.__T
@T.setter @T.setter
def T(self,value): self.__T = SIfloat(value) def T(self,value): self.__T.value = SIfloat(value)
@property @property
def phi(self): return Param('phi', self.__phi) def phi(self): return self.__phi
@phi.setter @phi.setter
def phi(self,value): self.__phi = SIfloat(value) def phi(self,value): self.__phi.value = SIfloat(value)
@property @property
def Rcx(self): return Param('Rcx', self.__Rcx) def Rcx(self): return self.__Rcx
@Rcx.setter @Rcx.setter
def Rcx(self,value): self.__Rcx = SIfloat(value) def Rcx(self,value): self.__Rcx.value = SIfloat(value)
@property @property
def Rcy(self): return Param('Rcy', self.__Rcy) def Rcy(self): return self.__Rcy
@Rcy.setter @Rcy.setter
def Rcy(self,value): self.__Rcy = SIfloat(value) def Rcy(self,value): self.__Rcy.value = SIfloat(value)
@property @property
def xbeta(self): return Param('xbeta', self.__xbeta) def xbeta(self): return self.__xbeta
@xbeta.setter @xbeta.setter
def xbeta(self,value): self.__xbeta = SIfloat(value) def xbeta(self,value): self.__xbeta.value = SIfloat(value)
@property @property
def ybeta(self): return Param('ybeta', self.__ybeta) def ybeta(self): return self.__ybeta
@ybeta.setter @ybeta.setter
def ybeta(self,value): self.__ybeta = SIfloat(value) def ybeta(self,value): self.__ybeta.value = SIfloat(value)
@property @property
def Rc(self): def Rc(self):
...@@ -236,8 +220,8 @@ class AbstractMirrorComponent(Component): ...@@ -236,8 +220,8 @@ class AbstractMirrorComponent(Component):
@Rc.setter @Rc.setter
def Rc(self,value): def Rc(self,value):
self.Rcx = SIfloat(value) self.Rcx.value = SIfloat(value)
self.Rcy = SIfloat(value) self.Rcy.value = SIfloat(value)
class mirror(AbstractMirrorComponent): class mirror(AbstractMirrorComponent):
def __init__(self,name,node1,node2,R=0,T=0,phi=0,Rcx=0,Rcy=0,xbeta=0,ybeta=0,mass=0, r_ap=0): def __init__(self,name,node1,node2,R=0,T=0,phi=0,Rcx=0,Rcy=0,xbeta=0,ybeta=0,mass=0, r_ap=0):
...@@ -271,10 +255,11 @@ class mirror(AbstractMirrorComponent): ...@@ -271,10 +255,11 @@ class mirror(AbstractMirrorComponent):
rtn = [] rtn = []
rtn.append('m {0} {1} {2} {3} {4} {5}'.format( rtn.append('m {0} {1} {2} {3} {4} {5}'.format(
self.name, self.R, self.T, self.phi, self.name, self.R.value, self.T.value, self.phi.value,
self.nodes[0].name, self.nodes[1].name)) self.nodes[0].name, self.nodes[1].name))
rtn.extend(super(mirror, self).getAttributeText()) for p in self._params:
rtn.extend(p.getFinesseText())
return rtn return rtn
...@@ -293,12 +278,12 @@ class beamSplitter(AbstractMirrorComponent): ...@@ -293,12 +278,12 @@ class beamSplitter(AbstractMirrorComponent):
self._requested_node_names.append(node3) self._requested_node_names.append(node3)
self._requested_node_names.append(node4) self._requested_node_names.append(node4)
self.__alpha = SIfloat(alpha) self.__alpha = AttrParam("alpha", self, SIfloat(alpha))
@property @property
def alpha(self): return Param('alpha', self.__alpha) def alpha(self): return self.__alpha
@alpha.setter @alpha.setter
def alpha(self,value): self.__alpha = SIfloat(value) def alpha(self,value): self.__alpha.value = SIfloat(value)
@staticmethod @staticmethod
def parseFinesseText(text): def parseFinesseText(text):
...@@ -325,12 +310,13 @@ class beamSplitter(AbstractMirrorComponent): ...@@ -325,12 +310,13 @@ class beamSplitter(AbstractMirrorComponent):
rtn = [] rtn = []
rtn.append('bs {0} {1} {2} {3} {4} {5} {6} {7} {8}'.format( rtn.append('bs {0} {1} {2} {3} {4} {5} {6} {7} {8}'.format(
self.name, self.R, self.T, self.phi, self.name, self.R.value, self.T.value, self.phi.value,
self.alpha, self.nodes[0].name, self.alpha.value, self.nodes[0].name,
self.nodes[1].name, self.nodes[2].name, self.nodes[1].name, self.nodes[2].name,
self.nodes[3].name)) self.nodes[3].name))
rtn.extend(super(beamSplitter, self).getAttributeText()) for p in self._params:
rtn.extend(p.getFinesseText())
return rtn return rtn
...@@ -348,17 +334,17 @@ class space(Component): ...@@ -348,17 +334,17 @@ class space(Component):
self._requested_node_names.append(node1) self._requested_node_names.append(node1)
self._requested_node_names.append(node2) self._requested_node_names.append(node2)
self._QItem = None self._QItem = None
self.__L = SIfloat(L) self.__L = Param("L", self, SIfloat(L))
self.__n = SIfloat(n) self.__n = Param("n", self, SIfloat(n))
@property @property
def L(self): return Param('L', self.__L) def L(self): return self.__L
@L.setter @L.setter
def L(self,value): self.__L = SIfloat(value) def L(self,value): self.__L,value = SIfloat(value)
@property @property
def n(self): return Param('n', self.__n) def n(self): return self.__n
@n.setter @n.setter
def n(self,value): self.__n = SIfloat(value) def n(self,value): self.__n.value = SIfloat(value)
@staticmethod @staticmethod
def parseFinesseText(text): def parseFinesseText(text):
...@@ -377,10 +363,17 @@ class space(Component): ...@@ -377,10 +363,17 @@ class space(Component):
raise exceptions.RuntimeError("Space Finesse code format incorrect '{0}'".format(text)) raise exceptions.RuntimeError("Space Finesse code format incorrect '{0}'".format(text))
def getFinesseText(self): def getFinesseText(self):
rtn = []
if self.__n == 1: if self.__n == 1:
return 's {0} {1} {2} {3}'.format(self.name, self.__L, self.nodes[0].name, self.nodes[1].name) rtn.append('s {0} {1} {2} {3}'.format(self.name, self.__L.value, self.nodes[0].name, self.nodes[1].name))
else: else:
return 's {0} {1} {2} {3} {4}'.format(self.name, self.__L, self.__n, self.nodes[0].name, self.nodes[1].name) rtn.append('s {0} {1} {2} {3} {4}'.format(self.name, self.__L.value, self.__n.value, self.nodes[0].name, self.nodes[1].name))
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
def getQGraphicsItem(self): def getQGraphicsItem(self):
if self._QItem == None: if self._QItem == None:
...@@ -411,13 +404,13 @@ class grating(Component): ...@@ -411,13 +404,13 @@ class grating(Component):
raise exceptions.RuntimeError("Grating must have between 2 and 4 ports") raise exceptions.RuntimeError("Grating must have between 2 and 4 ports")
self.__n = n self.__n = n
self.__d = SIfloat(d) self.__d = Param("d", self, SIfloat(d))
self.__eta_0 = SIfloat(eta_0) self.__eta_0 = AttrParam("eta_0", self, SIfloat(eta_0))
self.__eta_1 = SIfloat(eta_1) self.__eta_1 = AttrParam("eta_1", self, SIfloat(eta_1))
self.__eta_2 = SIfloat(eta_2) self.__eta_2 = AttrParam("eta_2", self, SIfloat(eta_2))
self.__eta_3 = SIfloat(eta_3) self.__eta_3 = AttrParam("eta_3", self, SIfloat(eta_3))
self.__rho_0 = SIfloat(rho_0) self.__rho_0 = AttrParam("rho_0", self, SIfloat(rho_0))
self.__alpha = SIfloat(alpha) self.__alpha = AttrParam("alpha", self, SIfloat(alpha))
@property @property
def n(self): return Param('n', self.__n) def n(self): return Param('n', self.__n)
...@@ -429,39 +422,39 @@ class grating(Component): ...@@ -429,39 +422,39 @@ class grating(Component):
self.__n = value self.__n = value
@property @property
def d(self): return Param('d', self.__d) def d(self): return self.__d
@d.setter @d.setter
def d(self, value): self.__d = SIfloat(value) def d(self, value): self.__d.value = SIfloat(value)
@property @property
def eta_0(self): return Param('eta_0', self.__eta_0) def eta_0(self): return self.__eta_0
@eta_0.setter @eta_0.setter
def eta_0(self, value): self.__eta_0 = SIfloat(value) def eta_0(self, value): self.__eta_0.value = SIfloat(value)
@property @property
def eta_1(self): return Param('eta_1', self.__eta_1) def eta_1(self): return self.__eta_1
@eta_1.setter @eta_1.setter
def eta_1(self, value): self.__eta_1 = SIfloat(value) def eta_1(self, value): self.__eta_1.value = SIfloat(value)
@property @property
def eta_2(self): return Param('eta_2', self.__eta_2) def eta_2(self): return self.__eta_2
@eta_2.setter @eta_2.setter
def eta_2(self, value): self.__eta_2 = SIfloat(value) def eta_2(self, value): self.__eta_2.value = SIfloat(value)
@property @property
def eta_3(self): return Param('eta_3', self.__eta_3) def eta_3(self): return self.__eta_3
@eta_3.setter @eta_3.setter
def eta_3(self, value): self.__eta_3 = SIfloat(value) def eta_3(self, value): self.__eta_3.value = SIfloat(value)
@property @property
def rho_0(self): return Param('rho_0', self.__rho_0) def rho_0(self): return self.__rho_0
@rho_0.setter @rho_0.setter
def rho_0(self, value): self.__rho_0 = SIfloat(value) def rho_0(self, value): self.__rho_0.value = SIfloat(value)
@property @property
def alpha(self): return Param('alpha', self.__alpha) def alpha(self): return self.__alpha
@alpha.setter @alpha.setter
def alpha(self, value): self.__alpha = SIfloat(value) def alpha(self, value): self.__alpha.value = SIfloat(value)
@staticmethod @staticmethod
def parseFinesseText(text): def parseFinesseText(text):
...@@ -500,19 +493,14 @@ class grating(Component): ...@@ -500,19 +493,14 @@ class grating(Component):
rtn = [] rtn = []
if self.__n == 2: if self.__n == 2:
rtn.append('gr{0} {1} {2} {3} {4}'.format(self.__n, self.name, self.__d, self.nodes[0].name, self.nodes[1].name)) rtn.append('gr{0} {1} {2} {3} {4}'.format(self.__n, self.name, self.__d.value, self.nodes[0].name, self.nodes[1].name))
elif self.__n == 3: elif self.__n == 3:
rtn.append('gr{0} {1} {2} {3} {4} {5}'.format(self.__n, self.name, self.__d, self.nodes[0].name, self.nodes[1].name, self.nodes[2].name)) rtn.append('gr{0} {1} {2} {3} {4} {5}'.format(self.__n, self.name, self.__d.value, self.nodes[0].name, self.nodes[1].name, self.nodes[2].name))
else: else:
rtn.append('gr{0} {1} {2} {3} {4} {5} {6}'.format(self.__n, self.name, self.__d, self.nodes[0].name, self.nodes[1].name, self.nodes[2].name, self.nodes[3].name)) rtn.append('gr{0} {1} {2} {3} {4} {5} {6}'.format(self.__n, self.name, self.__d.value, self.nodes[0].name, self.nodes[1].name, self.nodes[2].name, self.nodes[3].name))
if self.eta_0 != 0: rtn.append("attr {0} eta_0 {1}".format(self.name,self.__eta_0)) for p in self._params:
if self.eta_1 != 0: rtn.append("attr {0} eta_1 {1}".format(self.name,self.__eta_1)) rtn.extend(p.getFinesseText())
if self.eta_2 != 0: rtn.append("attr {0} eta_2 {1}".format(self.name,self.__eta_2))
if self.eta_3 != 0: rtn.append("attr {0} eta_3 {1}".format(self.name,self.__eta_3))
if self.rho_0 != 0: rtn.append("attr {0} rho_0 {1}".format(self.name,self.__rho_0))
if self.alpha != 0: rtn.append("attr {0} alpha {1}".format(self.name,self.__alpha))
# TODO: implement Rcx, Rcy, Rc
return rtn return rtn
...@@ -529,12 +517,12 @@ class isolator(Component): ...@@ -529,12 +517,12 @@ class isolator(Component):
self._requested_node_names.append(node1) self._requested_node_names.append(node1)
self._requested_node_names.append(node2) self._requested_node_names.append(node2)
self.__S = SIfloat(S) self.__S = Param("S",self,SIfloat(S))
@property @property
def S(self): return Param('S', self.__S) def S(self): return self.__S
@S.setter @S.setter
def S(self, value): self.__S = SIfloat(value) def S(self, value): self.__S.value = SIfloat(value)
@staticmethod @staticmethod
def parseFinesseText(text): def parseFinesseText(text):
...@@ -551,7 +539,12 @@ class isolator(Component): ...@@ -551,7 +539,12 @@ class isolator(Component):
raise exceptions.RuntimeError("Isolator Finesse code format incorrect '{0}'".format(text)) raise exceptions.RuntimeError("Isolator Finesse code format incorrect '{0}'".format(text))
def getFinesseText(self): def getFinesseText(self):
return 'isol {0} {1} {2} {3}'.format(self.name, self.S, self.nodes[0].name, self.nodes[1].name) rtn = ['isol {0} {1} {2} {3}'.format(self.name, self.S.value, self.nodes[0].name, self.nodes[1].name)]
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
def getQGraphicsItem(self): def getQGraphicsItem(self):
if self._QItem == None: if self._QItem == None:
...@@ -566,12 +559,12 @@ class lens(Component): ...@@ -566,12 +559,12 @@ class lens(Component):
self._requested_node_names.append(node1) self._requested_node_names.append(node1)
self._requested_node_names.append(node2) self._requested_node_names.append(node2)
self.__f = SIfloat(f) self.__f = Param("f", self, SIfloat(f))
@property @property
def f(self): return Param('f', self.__f) def f(self): return self.__f
@f.setter @f.setter
def f(self, value): self.__f = SIfloat(value) def f(self, value): self.__f.value = SIfloat(value)
@staticmethod @staticmethod
def parseFinesseText(text): def parseFinesseText(text):
...@@ -588,7 +581,89 @@ class lens(Component): ...@@ -588,7 +581,89 @@ class lens(Component):
raise exceptions.RuntimeError("Lens Finesse code format incorrect '{0}'".format(text)) raise exceptions.RuntimeError("Lens Finesse code format incorrect '{0}'".format(text))
def getFinesseText(self): def getFinesseText(self):
return 'lens {0} {1} {2} {3}'.format(self.name, self.f, self.nodes[0].name, self.nodes[1].name) rtn = ['lens {0} {1} {2} {3}'.format(self.name, self.f.value, self.nodes[0].name, self.nodes[1].name)]
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
def getQGraphicsItem(self):
if self._QItem == None:
self._QItem = pykat.gui.graphics.SpaceQGraphicsItem(self) # TODO: make lens graphic
return self._QItem
class modulator(Component):
def __init__(self, name, f, midx, order, modulation_type, node1, node2, phase=0):
Component.__init__(self, name)
self._requested_node_names.append(node1)
self._requested_node_names.append(node2)
self.__f = Param("f", self, SIfloat(f))
self.__midx = Param("midx", self, SIfloat(midx))
self.__phase = Param("phase", self, SIfloat(phase))
self.__order = order
self.type = modulation_type
@property
def f(self): return self.__f
@f.setter
def f(self, value): self.__f.value = SIfloat(value)
@property
def midx(self): return self.__midx
@midx.setter
def midx(self, value): self.__midx.value = SIfloat(value)
@property
def phase(self): return self.__phase
@phase.setter
def phase(self, value): self.__phase.value = SIfloat(value)
@property
def order(self): return self.__order
@order.setter
def order(self, value):
if order <= 1 and order > 6:
raise pkex.BasePyKatException("modulator order must be between 1 and 6")
self.__order = int(value)
@property
def type(self): return self.__type
@type.setter
def type(self, value):
if value != "am" and value != "pm":
raise pkex.BasePyKatException("Modulator type must be am (amplitude modulation) or pm (phase modulation)")
self.__type = str(value)
@staticmethod
def parseFinesseText(text):
v = text.split(" ")
if v[0] != "mod":
raise exceptions.RuntimeError("'{0}' not a valid Finesse modulator command".format(text))
v.pop(0) # remove initial value
if len(v) == 7:
return modulator(v[0], v[1], v[2], v[3], v[4], v[5], v[6])
if len(v) == 8:
return modulator(v[0], v[1], v[2], v[3], v[4], v[6], v[7], phase=v[5])
else:
raise pkex.BasePyKatException("Modulator Finesse code format incorrect '{0}'".format(text))
def getFinesseText(self):
rtn = ['mod {0} {1} {2} {3} {4} {5} {6} {7}'.format(self.name, self.f, self.midx, self.order, self.type, self.phase, self.nodes[0].name, self.nodes[1].name)]
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
def getQGraphicsItem(self): def getQGraphicsItem(self):
if self._QItem == None: if self._QItem == None:
...@@ -602,24 +677,25 @@ class laser(Component): ...@@ -602,24 +677,25 @@ class laser(Component):
self._requested_node_names.append(node) self._requested_node_names.append(node)
self.__power = float(P) self.__power = Param("P", self, SIfloat(P))
self.__f_offset = float(f_offset) self.__f_offset = Param("f", self, SIfloat(f_offset))
self.__phase = float(phase) self.__phase = Param("phase", self, SIfloat(phase))
self.__noise = AttrParam("noise", self, 0)
@property @property
def power(self): return Param('P', self.__power) def power(self): return self.__power
@power.setter @power.setter
def power(self,value): self.__power = float(value) def power(self,value): self.__power.value = float(value)
@property @property
def f_offset(self): return Param('f', self.__f_offset) def f(self): return self.__f_offset
@f_offset.setter @f.setter
def f_offset(self,value): self.__f_offset = float(value) def f(self,value): self.__f_offset.value = float(value)
@property @property
def phase(self): return Param('phase', self.__phase) def phase(self): return self.__phase
@phase.setter @phase.setter
def phase(self,value): self.__phase = float(value) def phase(self,value): self.__phase.value = float(value)
@staticmethod @staticmethod
def parseFinesseText(text): def parseFinesseText(text):
...@@ -638,7 +714,12 @@ class laser(Component): ...@@ -638,7 +714,12 @@ class laser(Component):
raise exceptions.FinesseParse("Laser Finesse code format incorrect '{0}'".format(text)) raise exceptions.FinesseParse("Laser Finesse code format incorrect '{0}'".format(text))
def getFinesseText(self): def getFinesseText(self):
return 'l {0} {1} {2} {3} {4}'.format(self.name, self.__power, self.__f_offset, self.__phase, self.nodes[0].name) rtn = ['l {0} {1} {2} {3} {4}'.format(self.name, self.__power.value, self.__f_offset.value, self.__phase.value, self.nodes[0].name)]
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
def getQGraphicsItem(self): def getQGraphicsItem(self):
if self._svgItem == None: if self._svgItem == None:
......
...@@ -57,14 +57,6 @@ class photodiode(Detector): ...@@ -57,14 +57,6 @@ class photodiode(Detector):
values = [] values = []
list.__init__(self,[SIfloat(value) for value in values]) list.__init__(self,[SIfloat(value) for value in values])
"""
def __setitem__(self, key, value):
list.__setitem__(self,key, SIfloat(value))
def append(self, value):
list.append(self,SIfloat(value))
"""
class __Phi(list): class __Phi(list):
def __convertValue(self, value): def __convertValue(self, value):
if value=="max": if value=="max":
...@@ -82,13 +74,6 @@ class photodiode(Detector): ...@@ -82,13 +74,6 @@ class photodiode(Detector):
return list.__getitem__(self,key) return list.__getitem__(self,key)
else: else:
return float(list.__getitem__(self,key)) return float(list.__getitem__(self,key))
"""
def __setitem__(self,key,value):
list.__setitem__(self,key, self.__convertValue(value))
def append(self, value):
list.append(self,self.__convertValue(value))
"""
@property @property
def f(self): return self.__f def f(self): return self.__f
...@@ -96,7 +81,6 @@ class photodiode(Detector): ...@@ -96,7 +81,6 @@ class photodiode(Detector):
@property @property
def phi(self): return self.__phi def phi(self): return self.__phi
def __init__(self, name, node, senstype="", num_demods=0, demods=[]): def __init__(self, name, node, senstype="", num_demods=0, demods=[]):
Detector.__init__(self, name, node) Detector.__init__(self, name, node)
if num_demods>2: if num_demods>2:
...@@ -109,10 +93,6 @@ class photodiode(Detector): ...@@ -109,10 +93,6 @@ class photodiode(Detector):
# Every second element into phi (starting at 2) # Every second element into phi (starting at 2)
self.__phi = self.__Phi(demods[1::2]) self.__phi = self.__Phi(demods[1::2])
"""
for i in demods[1::2]:
self.__phi.append(i)
"""
@staticmethod @staticmethod
def parseFinesseText(text): def parseFinesseText(text):
......
import exceptions import exceptions
class BasePyKatException(Exception): class BasePyKatException(Exception):
def __init__(self, msg): def __init__(self, msg):
self.__msg = msg self.__msg = msg
......
...@@ -34,14 +34,14 @@ import pykat ...@@ -34,14 +34,14 @@ import pykat
import warnings import warnings
import re import re
import pykat.exceptions as pkex
from pykat.node_network import NodeNetwork from pykat.node_network import NodeNetwork
from pykat.detectors import Detector from pykat.detectors import Detector
from pykat.components import Component from pykat.components import Component
from pykat.commands import Command, xaxis from pykat.commands import Command, xaxis
from pykat.gui.gui import pyKatGUI from pykat.gui.gui import pyKatGUI
import pykat.exceptions as pkex
from PyQt4.QtCore import QCoreApplication from PyQt4.QtCore import QCoreApplication
from PyQt4.QtGui import QApplication from PyQt4.QtGui import QApplication
...@@ -265,6 +265,8 @@ class kat(object): ...@@ -265,6 +265,8 @@ class kat(object):
obj = pykat.components.isolator.parseFinesseText(line) obj = pykat.components.isolator.parseFinesseText(line)
elif(first[0:4] == "lens"): elif(first[0:4] == "lens"):
obj = pykat.components.lens.parseFinesseText(line) obj = pykat.components.lens.parseFinesseText(line)
elif(first[0:3] == "mod"):
obj = pykat.components.modulator.parseFinesseText(line)
elif(first[0:2] == "pd"): elif(first[0:2] == "pd"):
obj = pykat.detectors.photodiode.parseFinesseText(line) obj = pykat.detectors.photodiode.parseFinesseText(line)
elif(first == "xaxis" or first == "xaxis*"): elif(first == "xaxis" or first == "xaxis*"):
...@@ -310,12 +312,12 @@ class kat(object): ...@@ -310,12 +312,12 @@ class kat(object):
def run(self, printout=0, printerr=0, save_output=False, save_kat=False,kat_name=None) : def run(self, printout=0, printerr=0, save_output=False, save_kat=False,kat_name=None) :
""" """
Runs the current simulation setup that has been built thus far. Runs the current simulation setup that has been built thus far.
It returns a katRun object which is populated with the various It returns a katRun or katRun2D object which is populated with the various
data from the simulation run. data from the simulation run.
""" """
try: try:
if not hasattr(self, "xaxis"): if not hasattr(self, "xaxis") and self.noxaxis != None and self.noxaxis == False:
raise pkex.BasePyKatException("No xaxis was defined") raise pkex.BasePyKatException("No xaxis was defined")
if len(self.__katdir) == 0: if len(self.__katdir) == 0:
...@@ -404,7 +406,7 @@ class kat(object): ...@@ -404,7 +406,7 @@ class kat(object):
r.runDateTime = datetime.datetime.now() r.runDateTime = datetime.datetime.now()
if p.returncode != 0: if p.returncode != 0:
raise FinesseRunError(err, katfile.name) raise pkex.FinesseRunError(err, katfile.name)
if printout == 1: print out if printout == 1: print out
if printerr == 1: print err if printerr == 1: print err
...@@ -467,7 +469,7 @@ class kat(object): ...@@ -467,7 +469,7 @@ class kat(object):
else: else:
return r return r
except FinesseRunError as fe: except pkex.FinesseRunError as fe:
print fe print fe
finally: finally:
print "" print ""
...@@ -505,7 +507,7 @@ class kat(object): ...@@ -505,7 +507,7 @@ class kat(object):
obj._on_kat_add(self) obj._on_kat_add(self)
except BasePyKatException as ex: except pkex.BasePyKatException as ex:
print ex print ex
def readOutFile(self, filename): def readOutFile(self, filename):
......
from pykat.SIfloat import SIfloat
import abc
import pykat.exceptions as pkex
class putable(object):
"""
Objects that inherit this should be able to have something `put` to it.
Essentially this means you could write Finesse commands like
put this parameter value
"""
__metaclass__ = abc.ABCMeta
def __init__(self, component_name, parameter_name, isPutable=True):
self._parameter_name = parameter_name
self._component_name = component_name
self._putter = None
self._isPutable = isPutable
@property
def isPutable(self): return self._isPutable
def put(self, var):
print "put"
if not isinstance(var, putter):
raise pkex.BasePyKatException("var was not something that can be `put` as a value")
if self._putter != None:
self._putter.put_count -= 1
self._putter = var
self._putter.put_count += 1
def _getPutFinesseText(self):
rtn = []
# if something is being put to this
if self._putter != None:
rtn.append("put {comp} {param} ${value}".format(comp=self._component_name, param=self._parameter_name, value=self._putter.put_name()))
return rtn
class putter(object):
"""
If an object can be put to something that is putable it should inherit this
object.
"""
def __init__(self, put_name, isPutter=True):
self._put_name = put_name
self.put_count = 0
self._isPutter = isPutter
@property
def isPutter(self): return self._isPutter
def put_name(self): return self._put_name
class Param(putable, putter):
def __init__(self, name, owner, value, isPutable=True, isPutter=True, isTunable=True, var_name=None):
self._name = name
self._owner = owner
self._value = value
self._isPutter = isPutter
self._isTunable = isTunable
self._owner._register_param(self)
if isPutter:
if var_name == None:
var_name = "var_{0}_{1}".format(owner.name, name)
putter.__init__(self, var_name, isPutter)
if isPutable:
putable.__init__(self, owner.name, name, isPutable)
@property
def name(self): return self._name
@property
def isTuneable(self): return self._isTunable
@property
def value(self): return self._value
@value.setter
def value(self, value):
self._value = value
def __str__(self): return str(self.value)
def __float__(self): return self.value
def getFinesseText(self):
rtn = []
if self.isPutable: rtn.extend(self._getPutFinesseText())
# if this parameter is being put somewhere then we need to
# set it as a variable
if self.isPutter and self.put_count > 0:
rtn.append("set {put_name} {comp} {param}".format(put_name=self.put_name(), comp=self._owner.name, param=self.name))
return rtn
def __mul__(self, a):
return float(self) * a
def __imul__(self, a):
return self.value * float(a)
__rmul__ = __mul__
def __add__(self, a):
return self.value + flota(a)
def __iadd__(self, a):
return self.value + float(a)
__radd__ = __add__
def __sub__(self, a):
return self.value - float(a)
def __isub__(self, a):
return self.value - float(a)
__rsub__ = __sub__
def __div__(self, a):
return self.value / float(a)
def __idiv__(self, a):
return self.value / complex(a)
def __pow__(self, q):
return self.value**q
def __neg__(self):
return -self.value
def __eq__(self, q):
return float(q) == self.value
def __ne__(self, q):
return float(q) != self.value
def __lt__(self, q):
return float(q) > self.value
def __gt__(self, q):
return float(q) < self.value
class AttrParam(Param):
"""
Certain parameters of a component are set using the Finesse `attr` command.
This inherits directly from a Param object so can be set whether this attribute
is putable or a putter.
If the value pf the parameter is not 0 the attr command will be printed.
"""
def getFinesseText(self):
rtn = []
if self.value != 0:
rtn.append("attr {0} {1} {2}".format(self._owner.name, self.name, self.value))
rtn.extend(super(AttrParam, self).getFinesseText())
return rtn
\ No newline at end of file
...@@ -95,7 +95,7 @@ class gauss_param(object): ...@@ -95,7 +95,7 @@ class gauss_param(object):
return gauss_param(self.__lambda, self.__nr, self.__q * complex(a)) return gauss_param(self.__lambda, self.__nr, self.__q * complex(a))
def __imul__(self, a): def __imul__(self, a):
self.__q += complex(a) self.__q *= complex(a)
return self return self
__rmul__ = __mul__ __rmul__ = __mul__
...@@ -185,6 +185,7 @@ class HG_gauss_beam(object): ...@@ -185,6 +185,7 @@ class HG_gauss_beam(object):
self.__ypre_const *= math.pow((1j*self._qy.imag * self._qy.conjugate)/(-1j*self._qy.imag * self._qy), self._m/2.0) self.__ypre_const *= math.pow((1j*self._qy.imag * self._qy.conjugate)/(-1j*self._qy.imag * self._qy), self._m/2.0)
def Unm(self, n, m, x, y): def Unm(self, n, m, x, y):
return self.__xpre_const * special # need to finish...
return self.__xpre_const
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment