diff --git a/pykat/__init__.py b/pykat/__init__.py index 6ba3fae76a35e6cf43d7de58741ec2e188ba5d64..82728bda2ad1d58dd9e9d97db4ebd23f2a4dea75 100644 --- a/pykat/__init__.py +++ b/pykat/__init__.py @@ -4,3 +4,4 @@ import finesse import components import detectors import commands + diff --git a/pykat/components.py b/pykat/components.py index 5c29a1a152eefe8845a94f771a166a791a3ebe1c..9c5205e92942c97047977e3897d112c2e30f48fb 100644 --- a/pykat/components.py +++ b/pykat/components.py @@ -858,13 +858,13 @@ class modulator(Component): return self._svgItem class laser(Component): - def __init__(self,name,node,P=1,f_offset=0,phase=0): + def __init__(self, name, node, P=1, f=0, phase=0): Component.__init__(self,name) self._requested_node_names.append(node) self.__power = Param("P", self, SIfloat(P), canFsig=True, fsig_name="amp") - self.__f_offset = Param("f", self, SIfloat(f_offset), canFsig=True, fsig_name="f") + self.__f_offset = Param("f", self, SIfloat(f), canFsig=True, fsig_name="f") self.__phase = Param("phase", self, SIfloat(phase), canFsig=True, fsig_name="phase") self.__noise = AttrParam("noise", self, None) self._svgItem = None @@ -902,9 +902,9 @@ class laser(Component): 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]) + return laser(values[0],values[4],P=values[1],f=values[2],phase=values[3]) elif len(values) == 4: - return laser(values[0],values[3],P=values[1],f_offset=values[2], phase=0) + return laser(values[0],values[3],P=values[1],f=values[2], phase=0) else: raise exceptions.FinesseParse("Laser Finesse code format incorrect '{0}'".format(text)) @@ -921,4 +921,67 @@ class laser(Component): self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/laser.svg", self, [(65,25,self.nodes[0])]) return self._svgItem + +class squeezer(Component): + def __init__(self, name, node, f=0, db=0, angle=0, phase=0): + Component.__init__(self,name) + + self._requested_node_names.append(node) + + self.__f = Param("f", self, SIfloat(f), canFsig=True, fsig_name="f") + self.__phase = Param("phase", self, SIfloat(phase), canFsig=True, fsig_name="phase") + self.__db = Param("db", self, SIfloat(db), canFsig=False, fsig_name="r") + self.__angle = Param("angle", self, SIfloat(angle), canFsig=False, fsig_name="angle") + self._svgItem = None + + @property + def db(self): return self.__db + @db.setter + def db(self,value): self.__db.value = float(value) + + @property + def angle(self): return self.__angle + @angle.setter + def angle(self,value): self.__angle.value = float(value) + + @property + def f(self): return self.__f + @f.setter + def f(self,value): self.__f.value = float(value) + + @property + def phase(self): return self.__phase + @phase.setter + def phase(self,value): self.__phase.value = float(value) + + def parseAttributes(self, values): + pass + + @staticmethod + def parseFinesseText(text): + values = text.split() + + if values[0] != "sq": + raise pkex.BasePyKatException("'{0}' not a valid Finesse squeezer command".format(text)) + + values.pop(0) # remove initial value + + if len(values) == 5: + return squeezer(values[0], values[4], f=values[1], db=values[2], angle=values[3]) + else: + raise exceptions.FinesseParse("Squeezer Finesse code format incorrect '{0}'".format(text)) + + def getFinesseText(self): + rtn = ['sq {0} {1} {2} {3} {4}'.format(self.name, self.f.value, self.db.value, self.angle.value, self.nodes[0].name)] + + for p in self._params: + rtn.extend(p.getFinesseText()) + + return rtn + + def getQGraphicsItem(self): + if self._svgItem == None: + self._svgItem = pykat.gui.graphics.ComponentQGraphicsItem(":/resources/laser.svg", self, [(65,25,self.nodes[0])]) + + return self._svgItem diff --git a/pykat/finesse.py b/pykat/finesse.py index 5cf8bc39320636abe95d4a9db54b1e66a69004fa..9d340d3c7fa315af1f057b279afef63ec9ffc58f 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -33,8 +33,7 @@ import pickle import pykat import warnings import re -import math - +import math import itertools import ctypes import ctypes.util @@ -374,6 +373,8 @@ class kat(object): self.__signals = Signals() self.constants = {} self.vacuum = [] + self.__prevrunfilename = None + self.printmatrix = None # initialise default block self.__currentTag= NO_BLOCK @@ -589,6 +590,8 @@ class kat(object): obj = pykat.components.space.parseFinesseText(line) elif(first == "l"): obj = pykat.components.laser.parseFinesseText(line) + elif(first == "sq"): + obj = pykat.components.squeezer.parseFinesseText(line) elif(first[0:2] == "bs"): obj = pykat.components.beamSplitter.parseFinesseText(line) elif(first[0:2] == "gr"): @@ -779,7 +782,7 @@ class kat(object): return Process(target=f__lkat_process, args=(callback, cmd, kwargs)) - def run(self, printout=0, printerr=0, plot=None, save_output=False, save_kat=False,kat_name=None) : + def run(self, printout=0, printerr=0, plot=None, save_output=False, save_kat=False, kat_name=None) : """ Runs the current simulation setup that has been built thus far. It returns a katRun or katRun2D object which is populated with the various @@ -909,6 +912,8 @@ class kat(object): print err sys.exit(1) + self.__prevrunfilename = katfile.name + root = os.path.splitext(katfile.name) base = os.path.basename(root[0]) outfile = root[0] + ".out" @@ -1019,6 +1024,52 @@ class kat(object): import gc print gc.get_referrers(obj) + def getMatrices(self): + + import scipy + from scipy.sparse import coo_matrix + + prev = self.noxaxis + + self.noxaxis = True + self.printmatrix = True + print "".join(self.generateKatScript()) + self.verbose = True + self.run(printout=1) + self.printmatrix = None + self.noxaxis = prev + + if self.__prevrunfilename == None: + return None + else: + + Mcarrier = None + Msignal = None + + if os.path.exists("klu_full_matrix_car.dat"): + M = np.loadtxt("klu_full_matrix_car.dat") + + if M.size > 0: + row = M[:,0]-1 + col = M[:,1]-1 + data = M[:,2] + 1j * M[:,3] + N = row.max()+1 + Mcarrier = coo_matrix((data,(row,col)), shape=(N,N)) + + + if os.path.exists("klu_full_matrix_sig.dat"): + M = np.loadtxt("klu_full_matrix_sig.dat") + + if M.size > 0: + row = M[:,0]-1 + col = M[:,1]-1 + data = M[:,2] + 1j * M[:,3] + N = row.max()+1 + Msignal = coo_matrix((data,(row,col)), shape=(N,N)) + + return (Mcarrier, Msignal) + + def hasNamedObject(self, name): return name in self.__components or name in self.__detectors or name in self.__commands @@ -1200,7 +1251,10 @@ class kat(object): if self.yaxis != None: out.append("yaxis {0}\n".format(self.yaxis)) - + + if self.printmatrix != None and self.printmatrix == True: + out.append("printmatrix\n") + if self.lambda0 != 1064e-9: out.append("lambda {0}\n".format(self.lambda0)) diff --git a/pykat/gui/graphics.py b/pykat/gui/graphics.py index e6dae457b9e0a69fcc598b1e40a73915bbfcba8f..35430023596fc62c7ea3fd4262eb02cb3e5952bd 100644 --- a/pykat/gui/graphics.py +++ b/pykat/gui/graphics.py @@ -140,7 +140,6 @@ class SpaceQGraphicsItem(QGraphicsLineItem): self.setLine(p.x(), p.y(), p.x()+x2-x1, p.y()+y2-y1) self.setPen(QPen(Qt.red, 3)) - class ComponentQGraphicsItem(QGraphicsObject): #(QtSvg.QGraphicsSvgItem): def __init__(self, svgfile, component, nodes): @@ -153,8 +152,6 @@ class ComponentQGraphicsItem(QGraphicsObject): #(QtSvg.QGraphicsSvgItem): self.__nodeGraphics = [] self.__component = weakref.ref(component) - # self.setRotation(432.34234) - # this signals the itemChange() method when this item is moved # used for refreshing the spaces between components self.setFlags(QGraphicsItem.ItemSendsGeometryChanges) @@ -181,7 +178,6 @@ class ComponentQGraphicsItem(QGraphicsObject): #(QtSvg.QGraphicsSvgItem): return self.__svggraphic.boundingRect() def paint(self, arg1, arg2, arg3): - self.__svggraphic.rotate(45) self.__svggraphic.paint( arg1, arg2, arg3)