diff --git a/examples/length_tuning.py b/examples/length_tuning.py
index 8a1c524195a93ea01bcf36eb0eead4b646a0e250..2729774f1129920388738b78e15822ed6a30e763 100644
--- a/examples/length_tuning.py
+++ b/examples/length_tuning.py
@@ -38,7 +38,7 @@ xaxis b1 phi lin 0 180 100
 yaxis deg     % plotting the phase of the results
 """
 
-kat = finesse.kat(tempdir = "/home/sleavey/Desktop/")
+kat = finesse.kat()
 kat.parseCommands(code)
 
 maxtem = np.arange(0, 2, 2)
diff --git a/pykat/components.py b/pykat/components.py
index 99c8cdbd4ea36b3955afcb99b2e76631effc1b30..7193049e4a4ec5df00b4b3f0fb7b35ceb1eca3bb 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -13,6 +13,7 @@ import pykat
 from pykat.node_network import *
 from pykat.exceptions import *
 import abc
+import copy
 
 from pykat.SIfloat import *
 from pykat.param import Param, AttrParam
@@ -70,8 +71,15 @@ class NodeGaussSetter(object):
         
 class Component(object):
     __metaclass__ = abc.ABCMeta
-    
-    def __init__(self, name):
+
+    def __new__(cls, *args, **kwargs):
+        # This creates an instance specific class for the component
+        # this enables us to add properties to instances rather than
+        # all classes
+        return object.__new__(type(cls.__name__, (cls,), {}), *args, **kwargs)
+        
+    def __init__(self, name=None):
+        
         self.__name = name
         self._svgItem = None
         self._requested_node_names = []
@@ -86,12 +94,20 @@ class Component(object):
         self.__id = next_component_id
         next_component_id += 1
         
-        # This creates an instance specific class for the component
-        # this enables us to add properties to instances rather than
-        # all classes
-        cls = type(self)
-        self.__class__ = type(cls.__name__, (cls,), {})
-    
+       
+        
+    def __deepcopy__(self, memo):
+        """
+        When deep copying a kat object we need to take into account
+        the instance specific properties.
+        """
+        result = self.__class__.__new__(self.__class__)
+        result.__dict__ = copy.deepcopy(self.__dict__, memo)
+        
+        result.__update_node_setters             
+        
+        return result
+        
     def _register_param(self, param):
         self._params.append(param)
     
diff --git a/pykat/detectors.py b/pykat/detectors.py
index 612b01c48f2765e976e894c6f8d83fba76633dc7..e6c5e93385170e704b7451636499853f3026cf1b 100644
--- a/pykat/detectors.py
+++ b/pykat/detectors.py
@@ -75,6 +75,8 @@ class BaseDetector(object) :
             else:
                 raise pkex.BasePyKatException("Nodes should be a list or tuple of node names or a singular node name as a string.")
                 
+                
+                  
     def _register_param(self, param):
         self._params.append(param)
         
@@ -349,7 +351,13 @@ class bp(Detector1):
 
 class pd(Detector1):
 
-    def __init__(self, name, num_demods, node_name, senstype=None, alternate_beam=False, pdtype=None, **kwargs):
+    def __new__(cls, *args, **kwargs):
+        # This creates an instance specific class for the component
+        # this enables us to add properties to instances rather than
+        # all classes
+        return object.__new__(type(cls.__name__, (cls,), {}), *args, **kwargs)
+        
+    def __init__(self, name=None, num_demods=1, node_name=None, senstype=None, alternate_beam=False, pdtype=None, **kwargs):
         BaseDetector.__init__(self, name, node_name)
         
         self.__num_demods = num_demods
@@ -394,11 +402,28 @@ class pd(Detector1):
             elif i<num_demods-1:
                 raise pkex.BasePyKatException("Missing demodulation phase {0} (phi{0})".format(i+1))
         
-        # define new class for assigning new attributes
-        cls = type(self)
-        self.__class__ = type(cls.__name__, (cls,), {})
     
         self.__set_demod_attrs()
+    
+    
+    def __deepcopy__(self, memo):
+        """
+        When deep copying a kat object we need to take into account
+        the instance specific properties.
+        """
+        
+        result = pd(self.name, self.num_demods, self.node.name)
+        
+        memo[id(self)] = result 
+        result.__dict__ = copy.deepcopy(self.__dict__, memo)
+
+        # Find all properties in class we are copying
+        # and deep copy these to the new class instance
+        for x in self.__class__.__dict__.items():
+            if isinstance(x[1], property):
+                setattr(result.__class__, x[0], x[1])
+                        
+        return result
         
     @property
     def senstype(self): return self.__senstype
diff --git a/pykat/finesse.py b/pykat/finesse.py
index e32e7859670cbad7b743d758769c768396740583..bc335e23355a34c0135ee2a3c8e817d00496b46c 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -183,10 +183,9 @@ class katRun(object):
     
     def __getitem__(self, value):
         idx = [i for i in range(len(self.ylabels)) if self.ylabels[i].split()[0] == str(value)]
-
+        out = None
+        
         if len(idx) > 0:
-            out = self.y[:, idx]
-            
             if len(idx) == 1:
                 if self.yaxis == "abs:deg":
                     out = self.y[:, idx[0]]
@@ -198,6 +197,9 @@ class katRun(object):
                 elif self.yaxis == "re:im":
                     out = self.y[:, idx[0]] + 1j*self.y[:, idx[1]]
             
+            if out == None:
+                out = self.y[:, idx]
+            
             if out.size == 1:
                 return out[0].squeeze()
             else:
@@ -375,10 +377,18 @@ Constant = namedtuple('Constant', 'name, value, usedBy')
     
 class kat(object):  
         
+    def __new__(cls, *args, **kwargs):
+        # This may seem like an arbitrary step but here we are creating a 
+        # new class that is a base class of itself. This is because when
+        # the kat object adds new components it also adds properties for
+        # each of these. There properties are unique to each kat object,
+        # but properties are part of the class definition. Thus if two
+        # kat objects share the same class definition they also have the
+        # same properties regardless of whether they have the actual
+        # object added to it. So we create an instance specific class.
+        return object.__new__(type(pykat.finesse.kat.__name__, (pykat.finesse.kat,), {}), *args, **kwargs)
+        
     def __init__(self, kat_file=None, kat_code=None, katdir="", katname="", tempdir=None, tempname=None):
-
-        cls = type(self)
-        self.__class__ = type(cls.__name__, (cls,), {})
         
         self.scene = None # scene object for GUI
         self.verbose = True
@@ -424,7 +434,30 @@ class kat(object):
         
         if kat_file != None:
             self.loadKatFile(kat_file)
-
+			
+    def __deepcopy__(self, memo):
+        """
+        When deep copying a kat object we need to take into account
+        the instance specific properties. This is because when
+        the kat object adds new components it also adds properties for
+        each of these. There properties are unique to each kat object,
+        but properties are part of the class definition. Thus if two
+        kat objects share the same class definition they also have the
+        same properties regardless of whether they have the actual
+        object added to it. So we create an instance specific class.
+        """
+        result = self.__class__.__new__(self.__class__)
+        memo[id(self)] = result
+        result.__dict__ = copy.deepcopy(self.__dict__, memo)
+        
+        # Find all properties in class we are copying
+        # and deep copy these to the new class instance
+        for x in self.__class__.__dict__.items():
+            if isinstance(x[1], property):
+                setattr(result.__class__, x[0], x[1])
+                        
+        return result
+		
     @property
     def signals(self): return self.__signals
 
@@ -1229,7 +1262,7 @@ class kat(object):
             # need to parse 2D outputs slightly different as they are effectively 2D matrices
             # written in linear form
             x = data[0::(1+self.x2axis.steps),0].squeeze()
-            y = data[0:(1+self.x2axis.steps),1].squeeze()
+            y = data[0:(1+self.x2axis.steps),1]
             # get rows and columns lined up so that we can reshape a single column of all x/y data
             # into a matrix
             z = data[:,2:].transpose().reshape(data.shape[1]-2, 1+self.xaxis.steps, 1+self.x2axis.steps).squeeze()
@@ -1242,7 +1275,7 @@ class kat(object):
             rows,cols = data.shape
             
             x = data[:,0].squeeze()
-            y = data[:,1:cols].squeeze()
+            y = data[:,1:cols]
         
             return [x, y, hdr]
 
diff --git a/pykat/node_network.py b/pykat/node_network.py
index 973d42c05c4e88d474ceab180ca4f0a60aeea625..e5db68304399b711c3844de435c9c2c3c09dc013 100644
--- a/pykat/node_network.py
+++ b/pykat/node_network.py
@@ -15,9 +15,18 @@ import pykat.exceptions as pkex
 from pykat.components import Component, NodeGaussSetter
 from pykat.detectors import BaseDetector as Detector
 from pykat.optics.gaussian_beams import beam_param
+from copy import deepcopy
 
 class NodeNetwork(object):
+    
+    def __new__(cls, *args, **kwargs):
+        # This creates an instance specific class for the component
+        # this enables us to add properties to instances rather than
+        # all classes
+        return object.__new__(type(cls.__name__, (cls,), {}), *args, **kwargs)
+        
     def __init__(self, kat):
+        
         self.__nodes = {}
         self.__kat = kat
         self.__nodeComponents = {} # dictionary of tuples containing which components are connected to a node
@@ -25,9 +34,8 @@ class NodeNetwork(object):
         self.__componentCallback = {}
         self.__node_id = 1
         
-        cls = type(self)
-        self.__class__ = type(cls.__name__, (cls,), {})
-    
+
+        
     @property
     def kat(self): return self.__kat