diff --git a/pykat/components.py b/pykat/components.py
index 52f32aa05d0a49d6d32921b1cfa1b4174b533bc9..613bb171d2a339d2413fe0b9d9b582920154311c 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -901,13 +901,14 @@ class grating(Component):
         return self._svgItem
 
 class isolator(Component):
-    def __init__(self, name, node1, node2, S = 0, node3="dump"):
+    def __init__(self, name, node1, node2, S = 0, node3="dump", option=0):
         Component.__init__(self, name)
         
         self._requested_node_names.append(node1)
         self._requested_node_names.append(node2)
         self._requested_node_names.append(node3)
         self._svgItem = None
+        self._option = option
         
         self.__S = Param("S",self,SIfloat(S))
         
@@ -920,20 +921,30 @@ class isolator(Component):
     def parseFinesseText(text):
         values = text.split()
 
-        if values[0] != "isol":
+        if values[0] != "isol" and values[0] != "isol*":
             raise pkex.BasePyKatException("'{0}' not a valid Finesse isolator command".format(text))
 
+        if values[0].endswith('*'):
+            option = 1
+        else:
+            option = 0
+            
         values.pop(0) # remove initial value
         
         if len(values) == 4:
-            return isolator(values[0], values[2], values[3], values[1])
+            return isolator(values[0], values[2], values[3], values[1], option=option)
         elif len(values) == 5:
-            return isolator(values[0], values[2], values[3], node3=values[4], S=values[1])
+            return isolator(values[0], values[2], values[3], node3=values[4], S=values[1], option=option)
         else:
             raise pkex.BasePyKatException("Isolator Finesse code format incorrect '{0}'".format(text))
         
     def getFinesseText(self):
-        rtn = ['isol {0} {1} {2} {3} {4}'.format(self.name, self.S.value, self.nodes[0].name, self.nodes[1].name, self.nodes[2].name)]
+        if self._option == 0:
+            cmd = "isol"
+        elif self._option == 1:
+            cmd = "isol*"
+            
+        rtn = ['{cmd} {0} {1} {2} {3} {4}'.format(self.name, self.S.value, self.nodes[0].name, self.nodes[1].name, self.nodes[2].name, cmd=cmd)]
         
         for p in self._params:
             rtn.extend(p.getFinesseText())
diff --git a/pykat/finesse.py b/pykat/finesse.py
index 109fd27bcdf81f28174824494140b93595ab575d..760c0723d1c3994bccc61ce8e5c97ebee5fe2617 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -1107,7 +1107,7 @@ class kat(object):
         except pkex.BasePyKatException as ex:
             print (ex)
 
-    def run(self, printout=0, printerr=0, plot=None, save_output=False, save_kat=False, kat_name=None, cmd_args=None, getTraceData=False):
+    def run(self, printout=0, printerr=0, plot=None, save_output=False, save_kat=False, kat_name=None, cmd_args=None, getTraceData=False, rethrowExceptions=False):
         """ 
         Runs the current simulation setup that has been built thus far.
         It returns a katRun or katRun2D object which is populated with the various
@@ -1124,6 +1124,8 @@ class kat(object):
         that Finesse performs, the keys are the node names and the values
         are the x and y beam parameters. If no tracing is done a None
         is returned.
+        
+        rethrowExceptions - if true exceptions will be thrown again rather than being excepted and calling sys.exit()
         """
         start = datetime.datetime.now()
         
@@ -1423,9 +1425,16 @@ class kat(object):
         except KeyboardInterrupt as ex:
             print("Keyboard interrupt caught, stopped simulation.")
         except pkex.FinesseRunError as ex:
-            pkex.PrintError("Error from Finesse:", ex)
+            if rethrowExceptions:
+                raise ex 
+            else:
+                pkex.PrintError("Error from Finesse:", ex)
+                
         except pkex.BasePyKatException as ex:
-            pkex.PrintError("Error from pykat:", ex)
+            if rethrowExceptions:
+                raise ex 
+            else:
+                pkex.PrintError("Error from pykat:", ex)
         finally:
             if self.verbose: print ("")
             if self.verbose: print ("Finished in " + str(datetime.datetime.now()-start))
@@ -1500,11 +1509,11 @@ class kat(object):
         for c in self.components.values():
             for n in c.nodes:
                 if n.isDump:
-                    while hasattr(kat.nodes, node_name):
+                    while hasattr(self.nodes, node_name):
                         node_name = "%s_%i" % (str(undumped_name_prefix), i)
                         i += 1
                         
-                    self.nodes.replaceNode(c, n, self.nodes.createNode(node_name % i))
+                    self.nodes.replaceNode(c, n, self.nodes.createNode(node_name))
         
   
     def getMatrices(self):
diff --git a/pykat/optics/maps.py b/pykat/optics/maps.py
index 8dd6ee902107c51dffe448150d16e3180203497e..1f170879f7a91666bf4e1eea3ba9bd48c9717909 100644
--- a/pykat/optics/maps.py
+++ b/pykat/optics/maps.py
@@ -1076,6 +1076,8 @@ def read_map(filename, mapFormat='finesse', scaling=1.0e-9):
         
         data = np.loadtxt(filename, dtype=np.float64,ndmin=2,comments='%')    
 
+        return surfacemap(name, maptype, size, center, step, scaling, data)
+        
     # Converts raw zygo and ligo mirror maps to the finesse
     # format. Based on the matlab scripts 'FT_read_zygo_map.m' and
     # 'FT_read_ligo_map.m'.
@@ -1288,15 +1290,15 @@ def read_map(filename, mapFormat='finesse', scaling=1.0e-9):
         # Changing NaN to zeros. Just to be able to plot the
         # map with surfacemap.plot().
         data[isNan] = 0 
-    
+        
+        return surfacemap(name, maptype, size, center, step, scaling, data, notNan)
         
     # TODO: Add options for reading virgo maps, and .xyz zygo
     # maps (need .xys file for this). Binary ligo-maps?
     # The intensity data is not used to anything here. Remove
     # or add to pykat?
 
-    return surfacemap(name, maptype, size, center, step,
-                      scaling, data, notNan)
+    
     
 
 def rnm(n,m,rho):
diff --git a/pykat/parallel.py b/pykat/parallel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f790e3aaec12940f344e6bbcf1db4ead55eb83f
--- /dev/null
+++ b/pykat/parallel.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Sun Jan 27 09:56:53 2013
+
+PyKat - Python interface and wrapper for FINESSE
+Copyright (C) 2013 Daniel David Brown
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Contact at ddb@star.sr.bham.ac.uk
+
+@author: Daniel Brown
+"""
+
+from IPython.parallel import Client
+import sys
+import os
+
+def _run(commands, pwd):
+    import os
+    os.chdir(pwd)
+    
+    import pykat
+
+    kat = pykat.finesse.kat()
+    kat.parseCommands(commands)
+    out = kat.run(rethrowExceptions=True)
+    
+    return out
+
+class parakat(object):
+    """
+    Uses the ipython clustering for running kat objects in parallel.
+    
+    To use this you must have started an ipython cluster on your computer.
+    From a new terminal use the command:
+        
+        ipcluster start -n 4
+        
+    This will start a cluster with 4 workers.
+    
+    To run a kat object use:
+    
+        pk = parakat()
+        pk.run(kat1)
+        pk.run(kat2)
+        pk.run(kat3)
+        
+        outs = pk.getResults()
+    
+    The list 'outs' will contain the katRun object you'd normal get if you 
+    had just called, kat1.run(), etc. The results list is matched to order
+    in which you run the kats.
+    
+    If you need to stop long running kat processes the chances are you will
+    also need to kill the ipython cluster process, as sometimes they carry
+    on running.
+    """
+    
+    def __init__(self):
+        self._rc = Client()
+        self._lview = self._rc.load_balanced_view()
+        self._lview.block = False
+        self._results = []
+        
+    def run(self, kat):
+        self._results.append(self._lview.apply_async(_run, "".join(kat.generateKatScript()), os.getcwd()))
+        
+    def getResults(self):
+        out = []
+        
+        self._lview.wait(self._results)
+        
+        for done in self._results:
+            out.append(done.get())
+            
+        return out