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
Branches
No related tags found
No related merge requests found
class Param(float):
def __new__(self,name,value):
return float.__new__(self,value)
import abc
import pykat.exceptions as pkex
def __init__(self,name,value):
self.__name = name
class puttable(object):
"""
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):
self.__T = temp
class Param(puttable, putter):
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
def temp(self):
return Param('Beer Temperature', self.__T)
def name(self): return self._name
@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 temp(self,value):
self.__T = float(value)
def __imul__(self, a):
return self.value * float(a)
__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
\ No newline at end of file
print c.T.getFinesseText()
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
import exceptions
from components import *
from structs import *
from pykat.param import Param, putter
class Command(object):
def __init__(self):
......@@ -47,39 +48,14 @@ class gauss(object):
if not values[0].startswith("gauss"):
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):
def __init__(self, scale, limits, comp, param, steps, axis_type="xaxis"):
self._axis_type = axis_type
self.x = putter("x1")
self.mx = putter("mx1")
if scale == "lin":
scale = Scale.linear
elif scale == "log":
......@@ -146,6 +122,8 @@ class xaxis(Command):
class x2axis(xaxis):
def __init__(self, scale, limits, comp, param, steps):
xaxis.__init__(self, scale, limits, comp, param, steps, axis_type="x2axis")
self.x = putter("x2")
self.mx = putter("mx2")
@staticmethod
def parseFinesseText(text):
......
......@@ -15,6 +15,7 @@ import pykat.gui.resources
import pykat.gui.graphics
from pykat.gui.graphics import *
from pykat.SIfloat import *
from pykat.param import Param, AttrParam
next_component_id = 1
......@@ -58,6 +59,7 @@ class Component(object):
self._requested_node_names = []
self._kat = None
self.tag = None
self._params = []
# store a unique ID for this component
global next_component_id
......@@ -70,6 +72,9 @@ class Component(object):
cls = type(self)
self.__class__ = type(cls.__name__, (cls,), {})
def _register_param(self, param):
self._params.append(param)
def _on_kat_add(self, kat):
"""
Called when this component has been added to a kat object.
......@@ -145,87 +150,66 @@ class Component(object):
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):
__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):
super(AbstractMirrorComponent, self).__init__(name)
self.__R = SIfloat(R)
self.__T = SIfloat(T)
self.__phi = SIfloat(phi)
self.__Rcx = SIfloat(Rcx)
self.__Rcy = SIfloat(Rcy)
self.__xbeta = SIfloat(xbeta)
self.__ybeta = SIfloat(ybeta)
self.__mass = SIfloat(mass)
self.__r_ap = 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
self.__R = Param("R", self, SIfloat(R))
self.__T = Param("T", self, SIfloat(T))
self.__phi = Param("phi", self, SIfloat(phi))
self.__Rcx = AttrParam("Rcx", self, SIfloat(Rcx))
self.__Rcy = AttrParam("Rcy", self, SIfloat(Rcy))
self.__xbeta = AttrParam("xbeta", self, SIfloat(xbeta))
self.__ybeta = AttrParam("ybeta", self, SIfloat(ybeta))
self.__mass = AttrParam("mass", self, SIfloat(mass))
self.__r_ap = AttrParam("r_ap", self, SIfloat(r_ap))
@property
def r_ap(self): return Param('r_ap', self.__r_ap)
def r_ap(self): return self.__r_ap
@r_ap.setter
def r_ap(self,value): self.__aperture = SIfloat(value)
def r_ap(self,value): self.__r_ap.value = SIfloat(value)
@property
def mass(self): return Param('mass', self.__mass)
def mass(self): return self.__mass
@mass.setter
def mass(self,value): self.__mass = SIfloat(value)
def mass(self,value): self.__mass.value = SIfloat(value)
@property
def R(self): return Param('R', self.__R)
def R(self): return self.__R
@R.setter
def R(self,value): self.__R = SIfloat(value)
def R(self,value): self.__R.value = SIfloat(value)
@property
def T(self): return Param('T', self.__T)
def T(self): return self.__T
@T.setter
def T(self,value): self.__T = SIfloat(value)
def T(self,value): self.__T.value = SIfloat(value)
@property
def phi(self): return Param('phi', self.__phi)
def phi(self): return self.__phi
@phi.setter
def phi(self,value): self.__phi = SIfloat(value)
def phi(self,value): self.__phi.value = SIfloat(value)
@property
def Rcx(self): return Param('Rcx', self.__Rcx)
def Rcx(self): return self.__Rcx
@Rcx.setter
def Rcx(self,value): self.__Rcx = SIfloat(value)
def Rcx(self,value): self.__Rcx.value = SIfloat(value)
@property
def Rcy(self): return Param('Rcy', self.__Rcy)
def Rcy(self): return self.__Rcy
@Rcy.setter
def Rcy(self,value): self.__Rcy = SIfloat(value)
def Rcy(self,value): self.__Rcy.value = SIfloat(value)
@property
def xbeta(self): return Param('xbeta', self.__xbeta)
def xbeta(self): return self.__xbeta
@xbeta.setter
def xbeta(self,value): self.__xbeta = SIfloat(value)
def xbeta(self,value): self.__xbeta.value = SIfloat(value)
@property
def ybeta(self): return Param('ybeta', self.__ybeta)
def ybeta(self): return self.__ybeta
@ybeta.setter
def ybeta(self,value): self.__ybeta = SIfloat(value)
def ybeta(self,value): self.__ybeta.value = SIfloat(value)
@property
def Rc(self):
......@@ -236,8 +220,8 @@ class AbstractMirrorComponent(Component):
@Rc.setter
def Rc(self,value):
self.Rcx = SIfloat(value)
self.Rcy = SIfloat(value)
self.Rcx.value = SIfloat(value)
self.Rcy.value = SIfloat(value)
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):
......@@ -271,10 +255,11 @@ class mirror(AbstractMirrorComponent):
rtn = []
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))
rtn.extend(super(mirror, self).getAttributeText())
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
......@@ -293,12 +278,12 @@ class beamSplitter(AbstractMirrorComponent):
self._requested_node_names.append(node3)
self._requested_node_names.append(node4)
self.__alpha = SIfloat(alpha)
self.__alpha = AttrParam("alpha", self, SIfloat(alpha))
@property
def alpha(self): return Param('alpha', self.__alpha)
def alpha(self): return self.__alpha
@alpha.setter
def alpha(self,value): self.__alpha = SIfloat(value)
def alpha(self,value): self.__alpha.value = SIfloat(value)
@staticmethod
def parseFinesseText(text):
......@@ -325,12 +310,13 @@ class beamSplitter(AbstractMirrorComponent):
rtn = []
rtn.append('bs {0} {1} {2} {3} {4} {5} {6} {7} {8}'.format(
self.name, self.R, self.T, self.phi,
self.alpha, self.nodes[0].name,
self.name, self.R.value, self.T.value, self.phi.value,
self.alpha.value, self.nodes[0].name,
self.nodes[1].name, self.nodes[2].name,
self.nodes[3].name))
rtn.extend(super(beamSplitter, self).getAttributeText())
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
......@@ -348,17 +334,17 @@ class space(Component):
self._requested_node_names.append(node1)
self._requested_node_names.append(node2)
self._QItem = None
self.__L = SIfloat(L)
self.__n = SIfloat(n)
self.__L = Param("L", self, SIfloat(L))
self.__n = Param("n", self, SIfloat(n))
@property
def L(self): return Param('L', self.__L)
def L(self): return self.__L
@L.setter
def L(self,value): self.__L = SIfloat(value)
def L(self,value): self.__L,value = SIfloat(value)
@property
def n(self): return Param('n', self.__n)
def n(self): return self.__n
@n.setter
def n(self,value): self.__n = SIfloat(value)
def n(self,value): self.__n.value = SIfloat(value)
@staticmethod
def parseFinesseText(text):
......@@ -377,10 +363,17 @@ class space(Component):
raise exceptions.RuntimeError("Space Finesse code format incorrect '{0}'".format(text))
def getFinesseText(self):
rtn = []
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:
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):
if self._QItem == None:
......@@ -411,13 +404,13 @@ class grating(Component):
raise exceptions.RuntimeError("Grating must have between 2 and 4 ports")
self.__n = n
self.__d = SIfloat(d)
self.__eta_0 = SIfloat(eta_0)
self.__eta_1 = SIfloat(eta_1)
self.__eta_2 = SIfloat(eta_2)
self.__eta_3 = SIfloat(eta_3)
self.__rho_0 = SIfloat(rho_0)
self.__alpha = SIfloat(alpha)
self.__d = Param("d", self, SIfloat(d))
self.__eta_0 = AttrParam("eta_0", self, SIfloat(eta_0))
self.__eta_1 = AttrParam("eta_1", self, SIfloat(eta_1))
self.__eta_2 = AttrParam("eta_2", self, SIfloat(eta_2))
self.__eta_3 = AttrParam("eta_3", self, SIfloat(eta_3))
self.__rho_0 = AttrParam("rho_0", self, SIfloat(rho_0))
self.__alpha = AttrParam("alpha", self, SIfloat(alpha))
@property
def n(self): return Param('n', self.__n)
......@@ -429,39 +422,39 @@ class grating(Component):
self.__n = value
@property
def d(self): return Param('d', self.__d)
def d(self): return self.__d
@d.setter
def d(self, value): self.__d = SIfloat(value)
def d(self, value): self.__d.value = SIfloat(value)
@property
def eta_0(self): return Param('eta_0', self.__eta_0)
def eta_0(self): return self.__eta_0
@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
def eta_1(self): return Param('eta_1', self.__eta_1)
def eta_1(self): return self.__eta_1
@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
def eta_2(self): return Param('eta_2', self.__eta_2)
def eta_2(self): return self.__eta_2
@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
def eta_3(self): return Param('eta_3', self.__eta_3)
def eta_3(self): return self.__eta_3
@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
def rho_0(self): return Param('rho_0', self.__rho_0)
def rho_0(self): return self.__rho_0
@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
def alpha(self): return Param('alpha', self.__alpha)
def alpha(self): return self.__alpha
@alpha.setter
def alpha(self, value): self.__alpha = SIfloat(value)
def alpha(self, value): self.__alpha.value = SIfloat(value)
@staticmethod
def parseFinesseText(text):
......@@ -500,19 +493,14 @@ class grating(Component):
rtn = []
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:
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:
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))
if self.eta_1 != 0: rtn.append("attr {0} eta_1 {1}".format(self.name,self.__eta_1))
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
for p in self._params:
rtn.extend(p.getFinesseText())
return rtn
......@@ -529,12 +517,12 @@ class isolator(Component):
self._requested_node_names.append(node1)
self._requested_node_names.append(node2)
self.__S = SIfloat(S)
self.__S = Param("S",self,SIfloat(S))
@property
def S(self): return Param('S', self.__S)
def S(self): return self.__S
@S.setter
def S(self, value): self.__S = SIfloat(value)
def S(self, value): self.__S.value = SIfloat(value)
@staticmethod
def parseFinesseText(text):
......@@ -551,7 +539,12 @@ class isolator(Component):
raise exceptions.RuntimeError("Isolator Finesse code format incorrect '{0}'".format(text))
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):
if self._QItem == None:
......@@ -566,12 +559,12 @@ class lens(Component):
self._requested_node_names.append(node1)
self._requested_node_names.append(node2)
self.__f = SIfloat(f)
self.__f = Param("f", self, SIfloat(f))
@property
def f(self): return Param('f', self.__f)
def f(self): return self.__f
@f.setter
def f(self, value): self.__f = SIfloat(value)
def f(self, value): self.__f.value = SIfloat(value)
@staticmethod
def parseFinesseText(text):
......@@ -588,7 +581,89 @@ class lens(Component):
raise exceptions.RuntimeError("Lens Finesse code format incorrect '{0}'".format(text))
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):
if self._QItem == None:
......@@ -602,24 +677,25 @@ class laser(Component):
self._requested_node_names.append(node)
self.__power = float(P)
self.__f_offset = float(f_offset)
self.__phase = float(phase)
self.__power = Param("P", self, SIfloat(P))
self.__f_offset = Param("f", self, SIfloat(f_offset))
self.__phase = Param("phase", self, SIfloat(phase))
self.__noise = AttrParam("noise", self, 0)
@property
def power(self): return Param('P', self.__power)
def power(self): return self.__power
@power.setter
def power(self,value): self.__power = float(value)
def power(self,value): self.__power.value = float(value)
@property
def f_offset(self): return Param('f', self.__f_offset)
@f_offset.setter
def f_offset(self,value): self.__f_offset = float(value)
def f(self): return self.__f_offset
@f.setter
def f(self,value): self.__f_offset.value = float(value)
@property
def phase(self): return Param('phase', self.__phase)
def phase(self): return self.__phase
@phase.setter
def phase(self,value): self.__phase = float(value)
def phase(self,value): self.__phase.value = float(value)
@staticmethod
def parseFinesseText(text):
......@@ -638,7 +714,12 @@ class laser(Component):
raise exceptions.FinesseParse("Laser Finesse code format incorrect '{0}'".format(text))
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):
if self._svgItem == None:
......
......@@ -57,14 +57,6 @@ class photodiode(Detector):
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):
def __convertValue(self, value):
if value=="max":
......@@ -82,13 +74,6 @@ class photodiode(Detector):
return list.__getitem__(self,key)
else:
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
def f(self): return self.__f
......@@ -96,7 +81,6 @@ class photodiode(Detector):
@property
def phi(self): return self.__phi
def __init__(self, name, node, senstype="", num_demods=0, demods=[]):
Detector.__init__(self, name, node)
if num_demods>2:
......@@ -109,10 +93,6 @@ class photodiode(Detector):
# Every second element into phi (starting at 2)
self.__phi = self.__Phi(demods[1::2])
"""
for i in demods[1::2]:
self.__phi.append(i)
"""
@staticmethod
def parseFinesseText(text):
......
import exceptions
class BasePyKatException(Exception):
def __init__(self, msg):
self.__msg = msg
......
......@@ -34,14 +34,14 @@ import pykat
import warnings
import re
import pykat.exceptions as pkex
from pykat.node_network import NodeNetwork
from pykat.detectors import Detector
from pykat.components import Component
from pykat.commands import Command, xaxis
from pykat.gui.gui import pyKatGUI
import pykat.exceptions as pkex
from PyQt4.QtCore import QCoreApplication
from PyQt4.QtGui import QApplication
......@@ -265,6 +265,8 @@ class kat(object):
obj = pykat.components.isolator.parseFinesseText(line)
elif(first[0:4] == "lens"):
obj = pykat.components.lens.parseFinesseText(line)
elif(first[0:3] == "mod"):
obj = pykat.components.modulator.parseFinesseText(line)
elif(first[0:2] == "pd"):
obj = pykat.detectors.photodiode.parseFinesseText(line)
elif(first == "xaxis" or first == "xaxis*"):
......@@ -310,12 +312,12 @@ class kat(object):
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.
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.
"""
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")
if len(self.__katdir) == 0:
......@@ -404,7 +406,7 @@ class kat(object):
r.runDateTime = datetime.datetime.now()
if p.returncode != 0:
raise FinesseRunError(err, katfile.name)
raise pkex.FinesseRunError(err, katfile.name)
if printout == 1: print out
if printerr == 1: print err
......@@ -467,7 +469,7 @@ class kat(object):
else:
return r
except FinesseRunError as fe:
except pkex.FinesseRunError as fe:
print fe
finally:
print ""
......@@ -505,7 +507,7 @@ class kat(object):
obj._on_kat_add(self)
except BasePyKatException as ex:
except pkex.BasePyKatException as ex:
print ex
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):
return gauss_param(self.__lambda, self.__nr, self.__q * complex(a))
def __imul__(self, a):
self.__q += complex(a)
self.__q *= complex(a)
return self
__rmul__ = __mul__
......@@ -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)
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