From fb0c2cb4e1882f1f07e2b45153e622554c6f531a Mon Sep 17 00:00:00 2001
From: Daniel Brown <Daniel@XPS15z.(none)>
Date: Sun, 10 Feb 2013 03:27:17 +0000
Subject: [PATCH] More changes on how it all works. kat.run() now returns a
 runkat object which contain all the varios information like timestamps, data,
 headers, version. Gui now has spaces connecting components up. Also added
 'Export to SVG' option which is nice, however the SVG renderer mucks up the
 gradients on the components

---
 pykat/commands.py      |  17 ++++-
 pykat/components.py    | 143 +++++++++++++++++++++++++----------
 pykat/detectors.py     |  22 ++++--
 pykat/finesse.py       | 165 +++++++++++++++++++++++++++++++----------
 pykat/gui/graphics.py  | 111 +++++++++++++++++++++++++--
 pykat/gui/gui.py       |  52 +++++++++++--
 pykat/gui/qt_gui.py    |  74 +++++++-----------
 pykat/gui/qt_gui.ui    | 100 ++++---------------------
 pykat/node_network.py  |  28 ++++++-
 pykat/plotting.py      |  91 +++++++++++------------
 pykat/spyder_crash.log |  20 -----
 scripts/test2.py       |  92 -----------------------
 scripts/test_kat.py    |  42 +++++++++--
 13 files changed, 557 insertions(+), 400 deletions(-)
 delete mode 100644 pykat/spyder_crash.log
 delete mode 100644 scripts/test2.py

diff --git a/pykat/commands.py b/pykat/commands.py
index 8af6057..4559d31 100644
--- a/pykat/commands.py
+++ b/pykat/commands.py
@@ -10,11 +10,26 @@ import exceptions
 from components import *
 from structs import *
 
-class Command:
+class Command(object):
     def getFinesseText(self):
         """ Base class for individual finesse optical components """    
         raise NotImplementedError("This function is not implemented")
         
+class cavity(Command):
+    def __init__(self, kat, 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);
+    
+    
 class xaxis(Command):
     
     def __init__(self, kat, scale, limits, comp, param, steps):
diff --git a/pykat/components.py b/pykat/components.py
index a86108d..a000fed 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -7,13 +7,14 @@ Created on Mon Jan 28 11:10:01 2013
 import exceptions
 import pykat.gui.resources
 import pykat
+import inspect
 
 from pykat.gui.graphics import *
 from pykat.node_network import *
 from PyQt4.QtGui import *
 from PyQt4.Qt import *
 
-class Component() :
+class Component(object) :
     def __init__(self, name, kat):
         self.__name = name
         self._svgItem = None
@@ -55,17 +56,15 @@ class Component() :
         
     name = property(__getname)
     
-class Param:
+class Param(float):
+    def __new__(self,name,value):
+        return float.__new__(self,value)
+         
     def __init__(self,name,value):
-        self.value = value
         self.__name = name
-    
-    def getname(self):
-        return self.__name
         
-    name = property(getname)
-            
-   
+    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):
         
@@ -74,36 +73,71 @@ class mirror(Component):
         self.node1 = self._addNode(node1)
         self.node2 = self._addNode(node2)
         
-        self.R = Param('R',R)
-        self.T = Param('R',T)
-        self.phi = Param('phi',phi)
-        self.Rcx = Param('rcx',Rcx)
-        self.Rcy = Param('rcy',Rcy)
-        self.xbeta = Param('xbeta',xbeta)
-        self.ybeta = Param('ybeta',ybeta)
-        
-    def _getRc(self):
+        self.__R = R
+        self.__T = T
+        self.__phi = phi
+        self.__Rcx = Rcx
+        self.__Rcy = Rcy
+        self.__xbeta = xbeta
+        self.__ybeta = ybeta
+            
+    @property
+    def R(self):
+        return Param('R',self.__R)
+    @R.setter
+    def R(self,value):
+        self.__R = value
+    @property
+    def T(self): return Param('T', self.__T)
+    @T.setter
+    def T(self,value): self.__T = value
+        
+    @property
+    def phi(self): return Param('phi', self.__phi)
+    @phi.setter
+    def phi(self,value): self.__phi = value
+    
+    @property
+    def Rcx(self): return Param('Rcx', self.__Rcx)
+    @Rcx.setter
+    def Rcx(self,value): self.__Rcx = value
+    @property
+    def Rcy(self): return Param('Rcy', self.__Rcy)
+    @Rcy.setter
+    def Rcy(self,value): self.__Rcy = value
+    
+    
+    @property
+    def xbeta(self): return Param('xbeta', self.__xbeta)
+    @xbeta.setter
+    def xbeta(self,value): self.__xbeta = value
+    @property
+    def ybeta(self): return Param('ybeta', self.__ybeta)
+    @ybeta.setter
+    def ybeta(self,value): self.__ybeta = value
+    
+    @property
+    def Rc(self):
         if self.Rcx == self.Rcy:
             return self.Rcx
         else:
             return [self.Rcx, self.Rcy]
     
-    def _setRc(self,value):
+    @Rc.setter
+    def Rc(self,value):
         self.Rcx = value
         self.Rcy = value
         
-    Rc = property(_getRc,_setRc)
-    
     def getFinesseText(self):        
         rtn = []
         rtn.append('m {0} {1} {2} {3} {4} {5}'.format(
-                self.name, self.R.value, self.T.value, self.phi.value,
+                self.name, self.__R, self.__T, self.__phi,
                 self.node1.name, self.node2.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))
-        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.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))
         
         return rtn
         
@@ -122,17 +156,31 @@ class space(Component):
         self.node1 = self._addNode(node1)
         self.node2 = self._addNode(node2)
         
-        self.length = Param('L',L)
-        self.refractive_index = Param('n',n)
-        
+        self.__L = L
+        self.__n = n
+        self._QItem = None
+        
+    @property
+    def L(self): return Param('L', self.__L)
+    @L.setter
+    def L(self,value): self.__L = value
+    @property
+    def n(self): return Param('n', self.__n)
+    @n.setter
+    def n(self,value): self.__n = value
+    
     def getFinesseText(self):
-        if self.refractive_index.value == 1:
-            return 's {0} {1} {2} {3}'.format(self.name, self.length.value, self.node1.name, self.node2.name)            
+        if self.__n == 1:
+            return 's {0} {1} {2} {3}'.format(self.name, self.__L, self.node1.name, self.node2.name)            
         else:
-            return 's {0} {1} {2} {3} {4}'.format(self.name, self.length.value, self.refractive_index.value, self.node1.name, self.node2.name)            
-       
-       
+            return 's {0} {1} {2} {3} {4}'.format(self.name, self.__L, self.__n, self.node1.name, self.node2.name)            
        
+    def getQGraphicsItem(self):
+        if self._QItem == None:
+            self._QItem = SpaceQGraphicsItem(self)
+        
+        return self._QItem  
+
        
 class laser(Component):
     def __init__(self,kat,name,node,P=1,f_offset=0,phase=0):
@@ -140,15 +188,30 @@ class laser(Component):
                 
         self.node = self._addNode(node)
         
-        self.power = Param('P', P)
-        self.f_offset = Param('f', f_offset)
-        self.phase = Param('phase',phase)
+        self.__power = P
+        self.__f_offset = f_offset
+        self.__phase = phase
         
+    @property
+    def power(self): return Param('P', self.__power)
+    @power.setter
+    def power(self,value): self.__power = value
+    
+    @property
+    def f_offset(self): return Param('f', self.__f_offset)
+    @f_offset.setter
+    def f_offset(self,value): self.__f_offset = value
+    
+    @property
+    def phase(self): return Param('phase', self.__phase)
+    @phase.setter
+    def phase(self,value): self.__phase = value
+    
     def getFinesseText(self):
-        if self.phase.value == 0 :
-            return 'l {0} {1} {2} {3}'.format(self.name, self.power.value, self.f_offset.value, self.node.name)            
+        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.value, self.f_offset.value, self.phase.value, self.node.name)            
+            return 'l {0} {1} {2} {4} {3}'.format(self.name, self.__power, self.__f_offset, self.__phase, self.node.name)            
          
     def getQGraphicsItem(self):
         if self._svgItem == None:
diff --git a/pykat/detectors.py b/pykat/detectors.py
index ae2173d..85c9ec7 100644
--- a/pykat/detectors.py
+++ b/pykat/detectors.py
@@ -14,11 +14,13 @@ from pykat.node_network import *
 from PyQt4.QtGui import *
 from PyQt4.Qt import *
 
-class Detector() :
+class Detector(object) :
     def __init__(self, name,node,kat):
         self.__name = name
         self._svgItem = None
         self._kat = kat
+        self.noplot = False
+        self.enabled = True
         
         kat.add(self)
         
@@ -52,11 +54,21 @@ class photodiode(Detector):
                     
                 
     def getFinesseText(self) :
-        if self._alternate_beam:
-            return "pd {0} {1}".format(self.name, self.__node.name)
-        else:
-            return "pd {0} {1}*".format(self.name, self.__node.name)
+        if self.enabled:    
+            rtn = []
+            
+            if self._alternate_beam:
+                rtn.append("pd {0} {1}".format(self.name, self.__node.name))
+            else:
+                rtn.append("pd {0} {1}*".format(self.name, self.__node.name))
+            
+            if self.noplot:
+                rtn.append("noplot {0}".format(self.name))
             
+            return rtn
+        else:
+            return None
+    
     def getQGraphicsItem(self):
         if self._svgItem == None:
             self._svgItem = ComponentQGraphicsItem(":/resources/photodiode_red.svg",self,[(-20,0,self.node)])
diff --git a/pykat/finesse.py b/pykat/finesse.py
index 8beec2f..064e11b 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -9,22 +9,55 @@ import exceptions
 import subprocess
 import tempfile
 import numpy as np
+import datetime
+#from colorama import Fore
+import pickle
 
-from colorama import Fore
 from pykat.node_network import NodeNetwork
 from pykat.detectors import Detector
 from pykat.components import Component
-from pykat.commands import Command
-from pykat.gui.gui import *
+from pykat.commands import Command, xaxis
+from pykat.gui.gui import openGUI
 
 class MissingFinesseEnvVar(Exception) :    
     def __str__(self) :
         return "The environment variable FINESSE_DIR was not defined"
 
-class kat:                    
-        
+class MissingFinesse(Exception) :    
+    def __str__(self) :
+        return "Could not find the finesse executable 'kat' in '{0}'," \
+               "or you do not have the permissions to run it." \
+               .format(os.environ.get('FINESSE_DIR'))
+    
+
+class katRun(object):
     def __init__(self):
+        self.runDateTime = datetime.datetime.now()
+        self.x = None
+        self.y = None
+        self.xlabel = None
+        self.ylabels = None
+        self.katScript = None
+        self.katVersion = None
+        
+    def saveKatRun(self, run, filename):
+        if not isinstance(run, katRun):
+            raise RuntimeError("run object must be a katRun type")
+        
+        with open(filename,'w') as outfile:
+            pickle.dump(run, outfile, pickle.HIGHEST_PROTOCOL)
     
+    @staticmethod
+    def loadKatRun(filename):
+        with open(filename,'r') as infile:
+            return pickle.load(infile)
+        
+        
+        
+class kat(object):                    
+        
+    def __init__(self):
+        
         self.__components = {}        
         self.__detectors = {}        
         self.__commands = {}        
@@ -32,28 +65,52 @@ class kat:
         self.nodes = NodeNetwork(self)  
 
         # Various         
-        self.phase = None
-        self.maxtem = None
-        self.noxaxis = None
-        
+        self.__phase = None
+        self.__maxtem = None
+        self.__noxaxis = None
         
-    def run(self, printout=1, printerr=1, save_output=False, save_kat=False
-            ,kat_name=None) :
-        """ Runs the current simulation """
+    @property
+    def maxtem(self): return self.__maxtem
+    @maxtem.setter
+    def maxtem(self,value): self.__maxtem = int(value)
+    
+    @property
+    def phase(self): return self.__phase
+    @phase.setter
+    def phase(self,value): self.__phase = int(value)
+    
+    @property
+    def noxaxis(self): return self.__noxaxis
+    @noxaxis.setter
+    def noxaxis(self,value): self.__noxaxis = bool(value)
+    
+    def run(self, printout=1, printerr=1, 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
+        data from the simulation run.
+        """
                 
         # Get the environment variable for where Finesse is stored
         self.__finesse_dir = os.environ.get('FINESSE_DIR')
                 
         if self.__finesse_dir == None :
-            raise exceptions.MissingFinesseEnvVar
+            raise MissingFinesseEnvVar()
         
-        katfile = tempfile.TemporaryFile(suffix=".kat")
         
-        katfile.writelines(self.generate())
+        r = katRun()
+        r.katScript = "".join(self.generateKatScript())
+        
+        katfile = tempfile.TemporaryFile(suffix=".kat")
+        katfile.writelines(r.katScript)
         katfile.flush()
         
-        kat_exec = os.path.join(self.__finesse_dir,'kat {0}'.format(
-                                                            katfile.name))   
+        kat_exec = os.path.join(self.__finesse_dir,'kat.exe')   
+        
+        if not (os.path.isfile(kat_exec) and os.access(kat_exec, os.X_OK)):
+            raise MissingFinesse()
+        
+        kat_exec = "{0} {1}".format(kat_exec, katfile.name)
                                                             
         p=subprocess.Popen(kat_exec, 
                          stdout=subprocess.PIPE, 
@@ -61,15 +118,27 @@ class kat:
 
         [out,err] = p.communicate()
         
-        if printout == 1: print Fore.GREEN + out
-        if printerr == 1: print Fore.RED + err
+        ix = out.find('build ') + 6
+        ix2 = out.find(')',ix)
+        r.katVersion = out[ix:ix2]
+        
+        r.runDateTime = datetime.datetime.now()
+        
+        if p.returncode != 0:
+            print err
+            return None
+        
+        if printout == 1: print out
+        if printerr == 1: print err
 
+        root = os.path.splitext(katfile.name)
+        base = os.path.basename(root[0])            
+        outfile = root[0] + ".out"
+                
+        [r.x,r.y,hdr] = self.readOutFile(outfile)
         
-        [root,ext] = os.path.splitext(katfile.name)
-        base = os.path.basename(root)            
-        outfile = root + ".out"
-            
-        [x,y,hdr] = self.readOutFile(outfile)
+        r.xlabel = hdr[0]
+        r.ylabels = hdr[1:]
         
         if save_output:        
             
@@ -78,6 +147,9 @@ class kat:
             cwd = os.path.os.getcwd()
             newoutfile = os.path.join(cwd,newoutfile)
             
+            if os.path.isfile(newoutfile):
+                os.remove(newoutfile)
+                
             os.rename(outfile, newoutfile)
 
             print "Output data saved to '{0}'".format(newoutfile)
@@ -88,6 +160,10 @@ class kat:
             
             cwd = os.path.os.getcwd()
             newkatfile = os.path.join(cwd, kat_name + ".kat")
+            
+            if os.path.isfile(newkatfile):
+                os.remove(newkatfile)
+              
             os.rename(katfile.name, newkatfile)         
             
             print "Kat file saved to '{0}'".format(newkatfile)
@@ -95,11 +171,12 @@ class kat:
 
         katfile.close()
         
-        return [x,y,hdr]
+        return r
         
     def add(self, obj) :
         
         if isinstance(obj, Component):
+            
             if obj.name in self.__components :
                 raise exceptions.ValueError("A component with name '{0}' has already been added".format([obj.name]))            
                         
@@ -108,6 +185,7 @@ class kat:
                         
             
         elif isinstance(obj, Detector):
+            
             if obj.name in self.__detectors :
                     raise exceptions.ValueError("A detector '{0}' has already been added".format(obj.name))
                     
@@ -115,12 +193,10 @@ class kat:
             self.__add_detector(obj)
             
         elif isinstance(obj, Command):
-            # dont error when adding same command, just replace it
-            #if obj.__class__.__name__ in self.__commands :
-            #    raise exceptions.ValueError("A command '{0}' has already been added".format([obj.__class__.__name__]))            
             
             self.__commands[obj.__class__.__name__] = obj
             self.__add_command(obj)
+            
         else :
             raise exceptions.ValueError("Object could not be added")
             
@@ -141,13 +217,14 @@ class kat:
         hdr = outfile.readline().replace('%','').replace('\n','').split(',')
 
         data = np.loadtxt(filename,comments='%')
-    	rows,cols = data.shape
-    	x = data[:,0]
-    	y = data[:,1:cols]
+        rows,cols = data.shape
         
-        return [x, y, hdr]
+        x = data[:,0]
+        y = data[:,1:cols].squeeze()
         
-    def generate(self) :
+        return [x, y, hdr]
+            
+    def generateKatScript(self) :
         """ Generates the kat file which can then be run """
         if len(self.__components) == 0 :
             raise exceptions.RuntimeError("No components have been added")
@@ -164,15 +241,27 @@ class kat:
                     out.append(txt + "\n")
             
         
-        for key in self.__detectors:        
-            out.append(self.__detectors[key].getFinesseText() + "\n")
+        for key in self.__detectors:
+            txt = self.__detectors[key].getFinesseText()
+            
+            if txt != None:
+                if isinstance(txt,list):
+                    for t in txt: out.append(t+ "\n")
+                else:
+                    out.append(txt + "\n")
         
         if self.noxaxis != None and self.noxaxis == True:
             out.append("noxaxis\n")
 
         for key in self.__commands:        
             if self.noxaxis == None or (self.noxaxis == True and isinstance(self.__commands[key], xaxis)):
-                out.append(self.__commands[key].getFinesseText() + "\n")
+                txt = self.__commands[key].getFinesseText()
+                
+                if txt != None:
+                    if isinstance(txt,list):
+                        for t in txt: out.append(t+ "\n")
+                    else:
+                        out.append(txt + "\n")
             
         if self.phase != None: out.append("phase {0}\n".format(self.phase))
         if self.maxtem != None: out.append("maxtem {0}\n".format(self.maxtem))            
@@ -192,10 +281,10 @@ class kat:
     def __add_detector(self, det):
 
         if not isinstance(det, Detector):
-            raise exceptions.ValueError("Argument is not of type Command")
+            raise exceptions.ValueError("Argument is not of type Detector")
         
         name = det.name
-        fget = lambda self: self.__get_command(name)
+        fget = lambda self: self.__get_detector(name)
         
         setattr(self.__class__, name, property(fget))
         setattr(self, '__det_' + name, det)                   
diff --git a/pykat/gui/graphics.py b/pykat/gui/graphics.py
index e462848..515a5ef 100644
--- a/pykat/gui/graphics.py
+++ b/pykat/gui/graphics.py
@@ -7,21 +7,120 @@ Created on Fri Feb 01 09:13:03 2013
 
 from PyQt4.QtGui import *
 from PyQt4.Qt import *
+import pykat.components
 
-class NodeQGraphicItem(QGraphicsRectItem):
-    pass
+nsize = 8
 
+class NodeQGraphicItem(QGraphicsRectItem):
+    
+    def __init__(self, node, x,y, *args, **kwargs):
+        QGraphicsRectItem.__init__(self, *args, **kwargs)
+        self.__node = node
+        
+        self.setPos(x,y)
+        
+        item = QGraphicsTextItem(node.name, self)
+        rect = item.boundingRect()       
+        item.setPos(-0.5*rect.width(), 0)
+        
+class SpaceQGraphicsItem(QGraphicsLineItem):
+    def __init__(self, spaceComponent):
+        QGraphicsLineItem.__init__(self)
+        self.__n1 = None
+        self.__n2 = None
+        self.__space = spaceComponent
+    
+        item = QGraphicsTextItem(self.__space.name, self)
+        rect = item.boundingRect()       
+        item.setPos(-0.5*rect.width(),-0.5*rect.height())
+    
+        self.refresh()
+        
+    def refresh(self):    
+        nodes = self.__space.getNodes()
+        
+        if self.__n1 == None:
+            self.__n1 = NodeQGraphicItem(nodes[0],0,0,-nsize/2,-nsize/2,nsize,nsize,self)
+            self.__n1.setPen(QPen(Qt.black))
+        
+        x1 = self.__n1.x
+        y1 = self.__n1.y
+            
+        conn = nodes[0].amIConnected(self.__space)
+        
+        if conn[0]:
+            self.__n1.setVisible(False)
+            # now check if a connected component was returned too
+            if conn[1] != None:
+                # so this node should be attached to something
+                # in this case we get the position of their node 
+                # and draw the the line from their
+                itm=conn[1].getQGraphicsItem()
+                x1 = itm.x() + itm.nodedx[conn[2]][0]
+                y1 = itm.y() + itm.nodedx[conn[2]][1]
+        else:
+            self.__n1.setBrush(QBrush(Qt.red))
+                
+        if self.__n2 == None:
+            self.__n2 = NodeQGraphicItem(nodes[1],0,0,-nsize/2,-nsize/2,nsize,nsize,self)
+            self.__n2.setPen(QPen(Qt.black))
+        
+        x2 = self.__n2.x
+        y2 = self.__n2.y
+        
+        conn = nodes[1].amIConnected(self.__space)
+        
+        if conn[0]:
+            self.__n2.setVisible(False)
+            # now check if a connected component was returned too
+            if conn[1] != None:
+                # so this node should be attached to something
+                # in this case we get the position of their node 
+                # and draw the the line from their
+                itm=conn[1].getQGraphicsItem()
+                x2 = itm.x() + itm.nodedx[conn[2]][0]
+                y2 = itm.y() + itm.nodedx[conn[2]][1]
+        else:
+            self.__n2.setBrush(QBrush(Qt.red))
+        
+        self.setLine(x1,y1,x2,y2)
+        self.setPen(QPen(Qt.red, 3))
+        
+        
+        
 class ComponentQGraphicsItem(QGraphicsSvgItem):
     
     def __init__(self, svgfile, component, nodes):
-        QGraphicsSvgItem.__init__(self, svgfile)
+        QGraphicsSvgItem.__init__(self,svgfile)
+        
         self.__component = component
-                
+        # this signals the itemChange() method when this item is moved
+        # used for refreshing the spaces between components
+        self.setFlags(QGraphicsItem.ItemSendsGeometryChanges)
+        self.nodedx = [] # stores the node square offsets
+        
         item = QGraphicsTextItem(component.name,self)
         rect = item.boundingRect()       
         item.setPos(-0.5*rect.width(),40-0.5*rect.height())
         
         for n in nodes:
-            node = NodeQGraphicItem(n[0],n[1],8,8,self)
+            self.nodedx.append([n[0],n[1]])
+            node = NodeQGraphicItem(n[2],n[0],n[1],-nsize/2,-nsize/2,nsize,nsize,self)
             node.setBrush(QBrush(Qt.red))
-            node.setPen(QPen(Qt.black))
\ No newline at end of file
+            node.setPen(QPen(Qt.black))
+        
+    def itemChange(self, change, value):
+        # if the item move then update any spaces
+        if change == QGraphicsItem.ItemPositionHasChanged:
+            nodes = self.__component.getNodes()
+            
+            for n in nodes:
+                conn = n.amIConnected(self.__component)
+                
+                if conn[0] and isinstance(conn[1],  pykat.components.space):
+                    conn[1].getQGraphicsItem().refresh()
+                    
+                
+                
+        return QGraphicsSvgItem.itemChange(self, change, value)
+            
\ No newline at end of file
diff --git a/pykat/gui/gui.py b/pykat/gui/gui.py
index 27d8abd..e512423 100644
--- a/pykat/gui/gui.py
+++ b/pykat/gui/gui.py
@@ -5,12 +5,15 @@ Created on Tue Jan 29 11:35:48 2013
 @author: Daniel
 """
 
+from pykat.components import Component
+from pykat.detectors import Detector
+
 from PyQt4 import QtGui, QtCore
 from PyQt4.Qt import *
-from PyQt4.QtGui import QCursor
+from PyQt4.QtGui import QCursor, QGraphicsItem
 from pykat.gui.graphics import *
 import qt_gui
-     
+        
 def openGUI(kat):
     app = QtGui.QApplication([""])
     pykatgui = pyKatGUI(kat)
@@ -20,16 +23,24 @@ def openGUI(kat):
 class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow):
     def __init__(self, kat,parent=None):
         super(pyKatGUI, self).__init__(parent)
+        
         self.setupUi(self)
+        self.graphicsView = pyKatGraphicsView(self.centralwidget)
+        self.graphicsView.setObjectName("graphicsView")
+        self.gridLayout.addWidget(self.graphicsView, 0, 0, 1, 1)
         
         # create a new scene
         self.__scene = QGraphicsScene()  
-
+        self.graphicsView.setRenderHint(QtGui.QPainter.Antialiasing)
+        
         brush = QBrush()
         brush.setStyle(Qt.CrossPattern)
         brush.setColor(QColor(230,230,230))
         self.__scene.setBackgroundBrush(brush)
         
+        self.actionExport_to_SVG.triggered.connect(lambda: self.exportToSVG())
+        self.actionClose.triggered.connect(lambda: self.close)
+
         # add scene to the graphics view
         self.graphicsView.setScene(self.__scene)
                 
@@ -50,8 +61,28 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow):
             
             if itm != None:
                 itm.setPos(0,0)
+                # uncomment this line to stop background bitmap caching of
+                # svg rendering. Important to make sure when rendering to 
+                # svg file that it is in a vector format. Gradients however
+                # don't work...
+                #itm.setCacheMode(QGraphicsItem.NoCache)
                 self.__scene.addItem(itm)
                 
+    def exportToSVG(self):
+        self.statusbar.showMessage("Saving to 'output.svg'...")
+        
+        svg = QSvgGenerator()
+        svg.setFileName("./output.svg")
+        svg.setSize(QSize(self.__scene.width(), self.__scene.height()))
+        svg.setViewBox(QRect(0,0,self.__scene.width(), self.__scene.height()))
+        svg.setTitle("pyKat output of example.kat")
+        
+        pntr = QPainter(svg)
+        self.__scene.render(pntr)
+        pntr.end()
+        
+        self.statusbar.showMessage("Complete: Saved to 'output.svg'")
+                
 class pyKatGraphicsView(QGraphicsView):
     def __init__(self,val):
         QGraphicsView.__init__(self,val)
@@ -72,7 +103,7 @@ class pyKatGraphicsView(QGraphicsView):
         item = self.itemAt(pt.x(),pt.y())
         
         if item != None :
-            if isinstance(item,Component):           
+            if isinstance(item, Component):           
                 menu.addSeparator()
                 menu.addAction("Edit")
                 menu.addAction("Delete")
@@ -110,8 +141,15 @@ class pyKatGraphicsView(QGraphicsView):
             self.setCursor(QCursor(Qt.ClosedHandCursor))
             
             item = self.__selected_item
-            pt_ = self.__prev_pt
+            #pt_ = self.__prev_pt
             pt = self.mapToScene(ev.pos())
             
-            item.moveBy(pt.x()-pt_.x(), pt.y()-pt_.y())
-            self.__prev_pt = pt
\ No newline at end of file
+            # smooth moving of item depending on where you click
+            #item.moveBy(pt.x()-pt_.x(), pt.y()-pt_.y())
+            # then snap to some integer value
+            snap = 10.0
+            item.setPos(int(round(pt.x()/snap)*snap),int(round(pt.y()/snap)*snap))
+            self.__prev_pt = pt
+            
+            
+            
\ No newline at end of file
diff --git a/pykat/gui/qt_gui.py b/pykat/gui/qt_gui.py
index ff018cf..deeecfa 100644
--- a/pykat/gui/qt_gui.py
+++ b/pykat/gui/qt_gui.py
@@ -1,5 +1,14 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'qt_gui.ui'
+#
+# Created: Sat Feb 09 17:34:29 2013
+#      by: PyQt4 UI code generator 4.9.5
+#
+# WARNING! All changes made in this file will be lost!
+
 from PyQt4 import QtCore, QtGui
-import gui
+#from pykat.gui.gui import pyKatGraphicsView
 
 try:
     _fromUtf8 = QtCore.QString.fromUtf8
@@ -9,8 +18,7 @@ except AttributeError:
 class Ui_MainWindow(object):
     def setupUi(self, MainWindow):
         MainWindow.setObjectName(_fromUtf8("MainWindow"))
-        MainWindow.resize(809, 611)
-        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
+        MainWindow.resize(833, 614)
         self.centralwidget = QtGui.QWidget(MainWindow)
         sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Preferred)
         sizePolicy.setHorizontalStretch(0)
@@ -20,81 +28,51 @@ class Ui_MainWindow(object):
         self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
         self.gridLayout = QtGui.QGridLayout(self.centralwidget)
         self.gridLayout.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
-        self.gridLayout.setMargin(5)
+        self.gridLayout.setMargin(2)
+        self.gridLayout.setSpacing(5)
         self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
-        self.graphicsView = gui.pyKatGraphicsView(self.centralwidget)
-        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
-        self.gridLayout.addWidget(self.graphicsView, 0, 0, 1, 1)
-        self.widget = QtGui.QWidget(self.centralwidget)
-        self.widget.setMinimumSize(QtCore.QSize(200, 0))
-        self.widget.setMaximumSize(QtCore.QSize(200, 16777215))
-        self.widget.setObjectName(_fromUtf8("widget"))
-        self.verticalLayout = QtGui.QVBoxLayout(self.widget)
-        self.verticalLayout.setMargin(0)
-        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
-        self.label = QtGui.QLabel(self.widget)
-        self.label.setText(QtGui.QApplication.translate("MainWindow", "Toolbox", None, QtGui.QApplication.UnicodeUTF8))
-        self.label.setObjectName(_fromUtf8("label"))
-        self.verticalLayout.addWidget(self.label)
-        self.toolBox = QtGui.QToolBox(self.widget)
-        self.toolBox.setMinimumSize(QtCore.QSize(0, 200))
-        self.toolBox.setFrameShape(QtGui.QFrame.Panel)
-        self.toolBox.setFrameShadow(QtGui.QFrame.Sunken)
-        self.toolBox.setObjectName(_fromUtf8("toolBox"))
-        self.tool_components = QtGui.QWidget()
-        self.tool_components.setGeometry(QtCore.QRect(0, 0, 176, 136))
-        self.tool_components.setObjectName(_fromUtf8("tool_components"))
-        self.toolBox.addItem(self.tool_components, _fromUtf8(""))
-        self.page_2 = QtGui.QWidget()
-        self.page_2.setGeometry(QtCore.QRect(0, 0, 176, 136))
-        self.page_2.setObjectName(_fromUtf8("page_2"))
-        self.toolBox.addItem(self.page_2, _fromUtf8(""))
-        self.verticalLayout.addWidget(self.toolBox)
-        self.widget_2 = QtGui.QWidget(self.widget)
-        self.widget_2.setMinimumSize(QtCore.QSize(0, 300))
-        self.widget_2.setObjectName(_fromUtf8("widget_2"))
-        self.verticalLayout.addWidget(self.widget_2)
-        self.gridLayout.addWidget(self.widget, 0, 1, 1, 1)
-        self.gridLayout.setColumnStretch(0, 4)
         MainWindow.setCentralWidget(self.centralwidget)
         self.menubar = QtGui.QMenuBar(MainWindow)
-        self.menubar.setGeometry(QtCore.QRect(0, 0, 809, 25))
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 833, 26))
         self.menubar.setObjectName(_fromUtf8("menubar"))
         self.menuFile = QtGui.QMenu(self.menubar)
-        self.menuFile.setTitle(QtGui.QApplication.translate("MainWindow", "File", None, QtGui.QApplication.UnicodeUTF8))
         self.menuFile.setObjectName(_fromUtf8("menuFile"))
         self.menuAbout = QtGui.QMenu(self.menubar)
-        self.menuAbout.setTitle(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8))
         self.menuAbout.setObjectName(_fromUtf8("menuAbout"))
         MainWindow.setMenuBar(self.menubar)
         self.statusbar = QtGui.QStatusBar(MainWindow)
         self.statusbar.setObjectName(_fromUtf8("statusbar"))
         MainWindow.setStatusBar(self.statusbar)
         self.actionClose = QtGui.QAction(MainWindow)
-        self.actionClose.setText(QtGui.QApplication.translate("MainWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
         self.actionClose.setObjectName(_fromUtf8("actionClose"))
         self.actionSave = QtGui.QAction(MainWindow)
-        self.actionSave.setText(QtGui.QApplication.translate("MainWindow", "Save", None, QtGui.QApplication.UnicodeUTF8))
         self.actionSave.setObjectName(_fromUtf8("actionSave"))
         self.actionOpen = QtGui.QAction(MainWindow)
-        self.actionOpen.setText(QtGui.QApplication.translate("MainWindow", "Open", None, QtGui.QApplication.UnicodeUTF8))
         self.actionOpen.setObjectName(_fromUtf8("actionOpen"))
         self.actionHelp = QtGui.QAction(MainWindow)
-        self.actionHelp.setText(QtGui.QApplication.translate("MainWindow", "Help", None, QtGui.QApplication.UnicodeUTF8))
         self.actionHelp.setObjectName(_fromUtf8("actionHelp"))
+        self.actionExport_to_SVG = QtGui.QAction(MainWindow)
+        self.actionExport_to_SVG.setObjectName(_fromUtf8("actionExport_to_SVG"))
         self.menuFile.addAction(self.actionSave)
         self.menuFile.addAction(self.actionOpen)
         self.menuFile.addSeparator()
+        self.menuFile.addAction(self.actionExport_to_SVG)
+        self.menuFile.addSeparator()
         self.menuFile.addAction(self.actionClose)
         self.menuAbout.addAction(self.actionHelp)
         self.menubar.addAction(self.menuFile.menuAction())
         self.menubar.addAction(self.menuAbout.menuAction())
 
         self.retranslateUi(MainWindow)
-        self.toolBox.setCurrentIndex(0)
         QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
     def retranslateUi(self, MainWindow):
-        self.toolBox.setItemText(self.toolBox.indexOf(self.tool_components), QtGui.QApplication.translate("MainWindow", "Page 1", None, QtGui.QApplication.UnicodeUTF8))
-        self.toolBox.setItemText(self.toolBox.indexOf(self.page_2), QtGui.QApplication.translate("MainWindow", "Page 2", None, QtGui.QApplication.UnicodeUTF8))
+        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuFile.setTitle(QtGui.QApplication.translate("MainWindow", "File", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuAbout.setTitle(QtGui.QApplication.translate("MainWindow", "About", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionClose.setText(QtGui.QApplication.translate("MainWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionSave.setText(QtGui.QApplication.translate("MainWindow", "Save", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionOpen.setText(QtGui.QApplication.translate("MainWindow", "Open", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionHelp.setText(QtGui.QApplication.translate("MainWindow", "Help", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionExport_to_SVG.setText(QtGui.QApplication.translate("MainWindow", "Export to SVG...", None, QtGui.QApplication.UnicodeUTF8))
 
diff --git a/pykat/gui/qt_gui.ui b/pykat/gui/qt_gui.ui
index daf51d9..db86f47 100644
--- a/pykat/gui/qt_gui.ui
+++ b/pykat/gui/qt_gui.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>809</width>
-    <height>611</height>
+    <width>833</width>
+    <height>614</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -20,96 +20,19 @@
      <verstretch>0</verstretch>
     </sizepolicy>
    </property>
-   <layout class="QGridLayout" name="gridLayout" rowstretch="0" columnstretch="4,0">
+   <layout class="QGridLayout" name="gridLayout" rowstretch="0" columnstretch="0">
     <property name="sizeConstraint">
      <enum>QLayout::SetDefaultConstraint</enum>
     </property>
     <property name="margin">
+     <number>2</number>
+    </property>
+    <property name="spacing">
      <number>5</number>
     </property>
     <item row="0" column="0">
      <widget class="QGraphicsView" name="graphicsView"/>
     </item>
-    <item row="0" column="1">
-     <widget class="QWidget" name="widget" native="true">
-      <property name="minimumSize">
-       <size>
-        <width>200</width>
-        <height>0</height>
-       </size>
-      </property>
-      <property name="maximumSize">
-       <size>
-        <width>200</width>
-        <height>16777215</height>
-       </size>
-      </property>
-      <layout class="QVBoxLayout" name="verticalLayout">
-       <item>
-        <widget class="QLabel" name="label">
-         <property name="text">
-          <string>Toolbox</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolBox" name="toolBox">
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>200</height>
-          </size>
-         </property>
-         <property name="frameShape">
-          <enum>QFrame::Panel</enum>
-         </property>
-         <property name="frameShadow">
-          <enum>QFrame::Sunken</enum>
-         </property>
-         <property name="currentIndex">
-          <number>0</number>
-         </property>
-         <widget class="QWidget" name="tool_components">
-          <property name="geometry">
-           <rect>
-            <x>0</x>
-            <y>0</y>
-            <width>176</width>
-            <height>136</height>
-           </rect>
-          </property>
-          <attribute name="label">
-           <string>Page 1</string>
-          </attribute>
-         </widget>
-         <widget class="QWidget" name="page_2">
-          <property name="geometry">
-           <rect>
-            <x>0</x>
-            <y>0</y>
-            <width>176</width>
-            <height>136</height>
-           </rect>
-          </property>
-          <attribute name="label">
-           <string>Page 2</string>
-          </attribute>
-         </widget>
-        </widget>
-       </item>
-       <item>
-        <widget class="QWidget" name="widget_2" native="true">
-         <property name="minimumSize">
-          <size>
-           <width>0</width>
-           <height>300</height>
-          </size>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </widget>
-    </item>
    </layout>
   </widget>
   <widget class="QMenuBar" name="menubar">
@@ -117,8 +40,8 @@
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>809</width>
-     <height>25</height>
+     <width>833</width>
+     <height>26</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -128,6 +51,8 @@
     <addaction name="actionSave"/>
     <addaction name="actionOpen"/>
     <addaction name="separator"/>
+    <addaction name="actionExport_to_SVG"/>
+    <addaction name="separator"/>
     <addaction name="actionClose"/>
    </widget>
    <widget class="QMenu" name="menuAbout">
@@ -160,6 +85,11 @@
     <string>Help</string>
    </property>
   </action>
+  <action name="actionExport_to_SVG">
+   <property name="text">
+    <string>Export to SVG...</string>
+   </property>
+  </action>
  </widget>
  <resources/>
  <connections/>
diff --git a/pykat/node_network.py b/pykat/node_network.py
index 7008044..53194fd 100644
--- a/pykat/node_network.py
+++ b/pykat/node_network.py
@@ -8,7 +8,7 @@ import exceptions
 from pykat.components import Component
 from pykat.detectors import Detector
 
-class NodeNetwork:
+class NodeNetwork(object):
     def __init__(self, kat):
         self._nodes = {}
         self.__kat = kat
@@ -59,7 +59,7 @@ class NodeNetwork:
             print "node: {0} connected:{1} {2}->{3} {4}".format(
                     n.name,n.isConnected(),comp1, comp2, detectors)
         
-class Node:
+class Node(object):
     
     def __init__(self, name):
         self._comp1 = None
@@ -87,13 +87,35 @@ class Node:
         else:
             # we must have a detector as we check above            
             self._detectors.append(obj)
-            
+    
     def getComponents(self):
         ''' Returns a tuple with the first being the 2 components that 
         connect to the node. The second item is a list of the detectors at the
         node'''
         return [(self._comp1, self._comp2),self._detectors]
         
+    def amIConnected(self, obj):
+        """
+        Checks if obj is connected oto the node. Returns true or false in tuple
+        with None or the other object and the node index which it is attached to
+        """ 
+        if obj == self._comp1:
+            if self._comp2 == None:
+                ix = -1
+            else:
+                ix = self._comp2.getNodes().index(self)
+                
+            return [True, self._comp2, ix]
+        elif obj == self._comp2:
+            if self._comp1 == None:
+                ix = -1
+            else:
+                ix = self._comp1.getNodes().index(self)
+                
+            return [True, self._comp1, ix]
+        else:
+            return [False, None]
+        
     def __getname(self):
         return self.__name      
         
diff --git a/pykat/plotting.py b/pykat/plotting.py
index d7a2914..8deec54 100644
--- a/pykat/plotting.py
+++ b/pykat/plotting.py
@@ -13,11 +13,10 @@ matplotlib.use(BACKEND)
 
 from matplotlib import rc
 import matplotlib.pyplot as plt
-from multiprocessing import Process
 
-def plot1D(x,y,hdr, title=""):
-        
-    plt.ion()
+mainpid = -1
+
+def plot1D(run, title=""):
     
     rc('font', **pp.font)
     rc('xtick',labelsize=pp.TICK_SIZE)
@@ -28,21 +27,16 @@ def plot1D(x,y,hdr, title=""):
     fig=plt.figure()
     fig.set_size_inches(pp.fig_size)
     fig.set_dpi(pp.FIG_DPI)
-    
-    #from itertools import cycle
-    #clist = matplotlib.rcParams['axes.color_cycle']
-    #colorcycler= cycle(clist)
-    
+        
     ax1 = fig.add_subplot(111)
-    ax1.set_xlim(np.min(x),np.max(x))
-    traces = ax1.plot(x,y)
+    ax1.set_xlim(np.min(run.x),np.max(run.x))
+    traces = ax1.plot(run.x,run.y)
     ax1.grid(pp.GRID)
     
-    if hdr != None:
-        ax1.set_xlabel(hdr[0])
-        legends = hdr[1:4]
-        ax1.legend(traces, legends, loc=0, shadow=pp.SHADOW,prop={'size':pp.LEGEND_SIZE})
-    
+    ax1.set_xlabel(run.xlabel)
+    legends = run.ylabels
+    ax1.legend(traces, legends, loc=0, shadow=pp.SHADOW,prop={'size':pp.LEGEND_SIZE})
+
     if pp.PRINT_TITLE:
         plt.title(title)
         
@@ -51,38 +45,39 @@ def plot1D(x,y,hdr, title=""):
     else:
         fig.canvas.manager.set_window_title('')
         
+    #plt.ion()
     plt.show()
     
 class pp():
-	# set some gobal settings first
-	BACKEND = 'Qt4Agg' # matplotlib backend
-	FIG_DPI=90 # DPI of on sceen plot
-	# Some help in calculating good figure size for Latex
-	# documents. Starting with plot size in pt,
-	# get this from LaTeX using \showthe\columnwidth
-	fig_width_pt = 484.0
-	inches_per_pt = 1.0/72.27  # Convert TeX pt to inches
-	golden_mean = (np.sqrt(5)-1.0)/2.0   # Aesthetic ratio
-	fig_width = fig_width_pt*inches_per_pt  # width in inches
-	fig_height = fig_width*golden_mean      # height in inches
-	fig_size = [fig_width,fig_height]
-	# some plot options:
-	LINEWIDTH = 1 # linewidths of traces in plot
-	AA = True # antialiasing of traces
-	USETEX = False # use Latex encoding in text
-	SHADOW = False # shadow of legend box
-	GRID = True # grid on or off
-	# font sizes for normal text, tick labels and legend
-	FONT_SIZE = 10 # size of normal text
-	TICK_SIZE = 10 # size of tick labels
-	LABEL_SIZE = 10 # size of axes labels
-	LEGEND_SIZE = 10 # size of legend
-	# font family and type
-	font = {'family':'sans-serif','sans-serif':['Helvetica'],'size':FONT_SIZE}
-	DPI=300 # DPI for saving via savefig
-	# print options given to savefig command:
-	print_options = {'dpi':DPI, 'transparent':True, 'bbox_inches':'tight', 'pad_inches':0.1}
-	# for Palatino and other serif fonts use:
-	#font = {'family':'serif','serif':['Palatino']}
-	SCREEN_TITLE = True # show title on screen?
-	PRINT_TITLE = False # show title in saved file?
\ No newline at end of file
+    # set some gobal settings first
+    BACKEND = 'Qt4Agg' # matplotlib backend
+    FIG_DPI=90 # DPI of on sceen plot
+    # Some help in calculating good figure size for Latex
+    # documents. Starting with plot size in pt,
+    # get this from LaTeX using \showthe\columnwidth
+    fig_width_pt = 484.0
+    inches_per_pt = 1.0/72.27  # Convert TeX pt to inches
+    golden_mean = (np.sqrt(5)-1.0)/2.0   # Aesthetic ratio
+    fig_width = fig_width_pt*inches_per_pt  # width in inches
+    fig_height = fig_width*golden_mean      # height in inches
+    fig_size = [fig_width,fig_height]
+    # some plot options:
+    LINEWIDTH = 1 # linewidths of traces in plot
+    AA = True # antialiasing of traces
+    USETEX = False # use Latex encoding in text
+    SHADOW = False # shadow of legend box
+    GRID = True # grid on or off
+    # font sizes for normal text, tick labels and legend
+    FONT_SIZE = 10 # size of normal text
+    TICK_SIZE = 10 # size of tick labels
+    LABEL_SIZE = 10 # size of axes labels
+    LEGEND_SIZE = 10 # size of legend
+    # font family and type
+    font = {'family':'sans-serif','sans-serif':['Helvetica'],'size':FONT_SIZE}
+    DPI=300 # DPI for saving via savefig
+    # print options given to savefig command:
+    print_options = {'dpi':DPI, 'transparent':True, 'bbox_inches':'tight', 'pad_inches':0.1}
+    # for Palatino and other serif fonts use:
+    #font = {'family':'serif','serif':['Palatino']}
+    SCREEN_TITLE = True # show title on screen?
+    PRINT_TITLE = False # show title in saved file?
\ No newline at end of file
diff --git a/pykat/spyder_crash.log b/pykat/spyder_crash.log
deleted file mode 100644
index ed933f3..0000000
--- a/pykat/spyder_crash.log
+++ /dev/null
@@ -1,20 +0,0 @@
-Traceback (most recent call last):
-  File "C:\Python27\lib\site-packages\spyderlib\spyder.py", line 2001, in main
-    mainwindow = run_spyder(app, options)
-  File "C:\Python27\lib\site-packages\spyderlib\spyder.py", line 1913, in run_spyder
-    main.setup()
-  File "C:\Python27\lib\site-packages\spyderlib\spyder.py", line 649, in setup
-    self.workingdirectory = WorkingDirectory(self, self.init_workdir)
-  File "C:\Python27\lib\site-packages\spyderlib\plugins\workingdirectory.py", line 207, in __init__
-    self.chdir(workdir)
-  File "C:\Python27\lib\site-packages\spyderlib\plugins\workingdirectory.py", line 334, in chdir
-    self.refresh_plugin()
-  File "C:\Python27\lib\site-packages\spyderlib\plugins\workingdirectory.py", line 258, in refresh_plugin
-    self.save_wdhistory()
-  File "C:\Python27\lib\site-packages\spyderlib\plugins\workingdirectory.py", line 289, in save_wdhistory
-    encoding.writelines(text, self.LOG_PATH)
-  File "C:\Python27\lib\site-packages\spyderlib\utils\encoding.py", line 200, in writelines
-    return write(os.linesep.join(lines), filename, encoding, mode)
-  File "C:\Python27\lib\site-packages\spyderlib\utils\encoding.py", line 191, in write
-    with open(filename, mode) as textfile:
-IOError: [Errno 22] invalid mode ('wb') or filename: u'C:\\Users\\Daniel\\.spyder2\\.workingdir'
diff --git a/scripts/test2.py b/scripts/test2.py
deleted file mode 100644
index 771c53e..0000000
--- a/scripts/test2.py
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/env python
-
-"""Finesse file for plotting test.out, Sat Feb  2 09:25:00 2013 """
-
-"""-----------------------------------------------------------------
-- Run from command line as: python test.py
-- Load from python script as: impoty test
-  And then use:
-  test.run() for plotting only
-  x,y=test.run() for plotting and loading the data
-  x,y=test.run(1) for only loading the data
------------------------------------------------------------------"""
-
-__author__ = "Finesse, http://www.gwoptics.org/finesse"
-
-import numpy as np
-import matplotlib
-BACKEND = 'Qt4Agg'
-matplotlib.use(BACKEND)
-from matplotlib import rc
-import matplotlib.pyplot as plt
-def run(noplot=None):
-	data = np.loadtxt('test.out',comments='%')
-	rows,cols=data.shape
-	x=data[:,0]
-	y=data[:,1:cols]
-	mytitle='test                Sat Feb  2 09:25:00 2013'
-	if (noplot==None):
-		# setting default font sizes
-		rc('font',**pp.font)
-		rc('xtick',labelsize=pp.TICK_SIZE)
-		rc('ytick',labelsize=pp.TICK_SIZE)
-		rc('text', usetex=pp.USETEX)
-		rc('axes', labelsize = pp.LABEL_SIZE)
-		fig=plt.figure()
-		fig.set_size_inches(pp.fig_size)
-		fig.set_dpi(pp.FIG_DPI)
-		from itertools import cycle
-		clist = matplotlib.rcParams['axes.color_cycle']
-		colorcycler= cycle(clist)
-		ax1 = fig.add_subplot(111)
-		ax1.set_xlim(0,360)
-		ax1.set_xlabel('phi [deg] (m2)')
-		trace1=ax1.plot(x, y[:,0], '-', color = next(colorcycler), label = 'pd2 n5 : ')
-		trace2=ax1.plot(x, y[:,1], '-', color = next(colorcycler), label = 'pd1 n4 : ')
-		traces = trace1 + trace2
-		legends = [t.get_label() for t in traces]
-		ax1.legend(traces, legends, loc=0, shadow=pp.SHADOW,prop={'size':pp.LEGEND_SIZE})
-		ax1.grid(pp.GRID)
-		if pp.PRINT_TITLE:
-			plt.title(mytitle)
-		if pp.SCREEN_TITLE:
-			fig.canvas.manager.set_window_title(mytitle)
-		else:
-			fig.canvas.manager.set_window_title('')
-	return (x,y)
-class pp():
-	# set some gobal settings first
-	BACKEND = 'Qt4Agg' # matplotlib backend
-	FIG_DPI=90 # DPI of on sceen plot
-	# Some help in calculating good figure size for Latex
-	# documents. Starting with plot size in pt,
-	# get this from LaTeX using \showthe\columnwidth
-	fig_width_pt = 484.0
-	inches_per_pt = 1.0/72.27  # Convert TeX pt to inches
-	golden_mean = (np.sqrt(5)-1.0)/2.0   # Aesthetic ratio
-	fig_width = fig_width_pt*inches_per_pt  # width in inches
-	fig_height = fig_width*golden_mean      # height in inches
-	fig_size = [fig_width,fig_height]
-	# some plot options:
-	LINEWIDTH = 1 # linewidths of traces in plot
-	AA = True # antialiasing of traces
-	USETEX = False # use Latex encoding in text
-	SHADOW = False # shadow of legend box
-	GRID = True # grid on or off
-	# font sizes for normal text, tick labels and legend
-	FONT_SIZE = 10 # size of normal text
-	TICK_SIZE = 10 # size of tick labels
-	LABEL_SIZE = 10 # size of axes labels
-	LEGEND_SIZE = 10 # size of legend
-	# font family and type
-	font = {'family':'sans-serif','sans-serif':['Helvetica'],'size':FONT_SIZE}
-	DPI=300 # DPI for saving via savefig
-	# print options given to savefig command:
-	print_options = {'dpi':DPI, 'transparent':True, 'bbox_inches':'tight', 'pad_inches':0.1}
-	# for Palatino and other serif fonts use:
-	#font = {'family':'serif','serif':['Palatino']}
-	SCREEN_TITLE = True # show title on screen?
-	PRINT_TITLE = False # show title in saved file?
-
-if __name__=="__main__":
-	run()
diff --git a/scripts/test_kat.py b/scripts/test_kat.py
index 62fc2fa..5b4cf27 100644
--- a/scripts/test_kat.py
+++ b/scripts/test_kat.py
@@ -1,29 +1,57 @@
-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()
 
 laser(kat,'l1','n1',1)
 space(kat,'s1','n1','n2',1)
+
 mirror(kat,'m1','n2','n3',0.8,0.2)
 space(kat,'s2','n3','n4',1)
 mirror(kat,'m2','n4','n5',0.7,0.3)
+cavity(kat, 'cav1','m1','n3','m2','n4')
 
 photodiode(kat,'pd_cav','n4')
 photodiode(kat,'pd_ref','n2')
 photodiode(kat,'pd_trs','n5')
 
-xaxis(kat, Scale.linear, [0,1e-6], kat.m2, kat.m2.xbeta, 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.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.maxtem = 1
+kat.openGUI()
 
-[x,y_0,hdr] = kat.run(printout=0,printerr=0)
 
-plot1D(x,y,hdr)
-- 
GitLab