diff --git a/pykat/commands.py b/pykat/commands.py
index 241f7b7d971efec41b6e3f0d382845bb70c8613a..5df7a6b28c25ca667709a71a4d7116516dc3c37a 100644
--- a/pykat/commands.py
+++ b/pykat/commands.py
@@ -34,6 +34,7 @@ class Command(object):
         self.tag = None
         self.__removed = False
         self.__name = name.strip("*")
+        self._putters_to_register = []
         
     def getFinesseText(self):
         """ Base class for individual finesse optical components """
@@ -48,10 +49,16 @@ class Command(object):
         Called when this component has been added to a kat object
         """
         self._kat = kat
+        
+        for _ in self._putters_to_register:
+            kat.registerVariable(_.name, _)
 
     def remove(self):
         self._kat.remove(self)
         self.__removed = True
+        
+        for _ in self._putters_to_register:
+            kat.unregisterVariable(_.name)
     
     @property
     def name(self): return self.__name
@@ -95,14 +102,19 @@ class func(Command):
         
         self.value = value
         self.noplot = False
+        self.enabled = True
+        
+        self.output = putter(name, self)
+        self._putters_to_register.append(self.output)
         
     def getFinesseText(self):
         rtn = []
 
-        if self.noplot:
-            rtn.append("noplot " + self.name)
+        if self.enabled:
+            if self.noplot:
+                rtn.append("noplot " + self.name)
         
-        rtn.append("func {name} = {value}".format(name=self.name, value=str(self.value)))
+            rtn.append("func {name} = {value}".format(name=self.name, value=str(self.value)))
 
         return rtn
 
@@ -118,10 +130,7 @@ class func(Command):
             return func(v2[0].split()[1], v2[1]) 
         else:
             raise pkex.BasePyKatException("'{0}' not a valid Finesse func command".format(line))
-        
-        
-        
-
+            
 
 class lock(Command):
     def __init__(self, name, variable, gain, accuracy, singleLock=False):
@@ -132,6 +141,10 @@ class lock(Command):
         self.__accuracy = accuracy
         self.singleLock = singleLock
         self.enabled = True
+        
+        
+        self.output = putter(name, self)
+        self._putters_to_register.append(self.output)
 
 
     @staticmethod
@@ -354,9 +367,12 @@ class xaxis(Command):
         
         self._axis_type = axis_type
 
-        self.x = putter("x1")
-        self.mx = putter("mx1")
+        self.x = putter("x1", self)
+        self.mx = putter("mx1", self)
 
+        self._putters_to_register.append(self.x)
+        self._putters_to_register.append(self.mx)
+        
         if scale == "lin":
             scale = Scale.linear
         elif scale == "log":
@@ -433,8 +449,11 @@ class xaxis(Command):
 class x2axis(xaxis):
     def __init__(self, scale, limits, param, steps, comp=None, axis_type="x2axis"):
         xaxis.__init__(self, scale, limits, param, steps, comp=comp, axis_type=axis_type)
-        self.x = putter("x2")
-        self.mx = putter("mx2")
+        self.x = putter("x2", self)
+        self.mx = putter("mx2", self)
+
+        self._putters_to_register.append(self.x)
+        self._putters_to_register.append(self.mx)
 
     @staticmethod
     def parseFinesseText(text):
diff --git a/pykat/finesse.py b/pykat/finesse.py
index cdb5a2ae1a44a2db553661393bfba3ee6229e0e3..94403c987e18b6ef6bdb566f87c4ffbd145b9e56 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -745,6 +745,7 @@ class kat(object):
         self.vacuum = []
         self.__prevrunfilename = None
         self.printmatrix = None
+        self.__variables = {}
         
         # initialise default block
         self.__currentTag= NO_BLOCK
@@ -1005,6 +1006,31 @@ class kat(object):
     def __str__(self):
          return "".join(self.generateKatScript())
          
+    def getVariable(self, name):
+        if name not in self.__variables:
+            raise pkex.BasePyKatException("Finesse variable `$%s` does not exist." % name)
+            
+        return self.__variables[name]
+    
+    def registerVariable(self, name, putter):
+        if '$' in name:
+            raise pkex.BasePyKatException("Finesse variable name `%s` should not include the `$` symbol as it is added internally." % name)
+            
+        assert(putter is not None)
+        assert(name == putter.name)
+        
+        if name in self.__variables:
+            raise pkex.BasePyKatException("Finesse variable name `%s` already exists." % name)
+            
+        self.__variables[name] = putter
+        
+    def unregisterVariable(self, name):
+        del self.__variables[name]
+    
+    def printVariables(self):
+        for key in self.__variables:
+            print("$" + key, "::::", "owner =", self.__variables[key].owner.name, ", use count =", self.__variables[key].putCount)
+    
     def parseCommands(self, commands, blocks=None, addToBlock=None):
         try:
             if addToBlock is not None and blocks is not None:
@@ -1182,6 +1208,8 @@ class kat(object):
                         after_process.append((line, self.__currentTag))
                     elif(first == "noplot"):
                         after_process.append((line, self.__currentTag))
+                    elif(first == "put" or first == "put*"):
+                        after_process.append((line, self.__currentTag))
                     else:
                         if self.verbose:
                             print ("Parsing `{0}` into pykat object not implemented yet, added as extra line.".format(line))
@@ -1231,7 +1259,30 @@ class kat(object):
                         raise pkex.BasePyKatException("noplot command `{0}` refers to non-existing detector".format(line))
                         
                     getattr(self, rest).noplot = True
+                
+                elif (first == "put" or first =="put*"):
+                    alt = first == "put*"
+                    
+                    values = line.split()
+                    obj = values[1]
+                    target = values[2]
+                    variable = values[3]
+                    
+                    if not hasattr(self, obj):
+                        raise pkex.BasePyKatException("put command `{0}` refers to non-existing component".format(line))
+                    
+                    obj = getattr(self, obj)
                     
+                    if not hasattr(obj, target):
+                        raise pkex.BasePyKatException("put command component `{0}` does not have a parameter `{1}`".format(line, target))
+                        
+                    target = getattr(obj, target)
+                    
+                    if not target.isPutable:
+                        raise pkex.BasePyKatException("put command `{0}` parameter `{1}` cannot be put to".format(line, target))
+                        
+                    target.put(self.getVariable(variable.replace('$', '')), alt)
+                 
                 elif (first == "scale"):
                     v = line.split()
                     accepted = ["psd","psd_hf","asd","asd_hf","meter", "ampere", "deg", "rad", "1/deg", "1/rad",]
@@ -1641,14 +1692,14 @@ class kat(object):
             #if len(self.detectors.keys()) > 0: 
             
             if hasattr(self, "x2axis") and self.noxaxis == False:
-                [r.x,r.y,r.z,hdr] = self.readOutFile(outfile)
+                [r.x, r.y, r.z, hdr] = self.readOutFile(outfile)
             
                 r.xlabel = hdr[0]
                 r.ylabel = hdr[1]
                 r.zlabels = [s.strip() for s in hdr[2:]]
                 #r.zlabels = map(str.strip, hdr[2:])
             else:
-                [r.x,r.y,hdr] = self.readOutFile(outfile)
+                [r.x, r.y, hdr] = self.readOutFile(outfile)
                 
                 r.xlabel = hdr[0]
                 r.ylabels = [s.strip() for s in hdr[1:]]
diff --git a/pykat/param.py b/pykat/param.py
index 264de77b1e3e13d2f01da656a3fb3b04b7ab474d..72740a8e73d2ed82c525db92e128e9c9fc6e4c75 100644
--- a/pykat/param.py
+++ b/pykat/param.py
@@ -12,7 +12,8 @@ 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
+    param.put(kat.xaxis.x)
+    
     """
     __metaclass__ = abc.ABCMeta
     
@@ -20,31 +21,44 @@ class putable(object):
         self._parameter_name = parameter_name
         self._component_name = component_name
         self._putter = None
+        self._alt = False
         self._isPutable  = isPutable
     
     @property
     def isPutable(self): return self._isPutable
     
-    def put(self, var):
-    
+    def put(self, var, alt):
         if not isinstance(var, putter):
-            raise pkex.BasePyKatException("var was not something that can be `put` as a value")
+            raise pkex.BasePyKatException("`%s` was not something that can be `put` to a parameter" % str(var))
         
-        if self._putter != None:
+        if self._putter is not None:
             self._putter.put_count -= 1
             self._putter.putees.remove(self)
         
         self._putter = var
+        self._alt = alt
         
-        if var != None:
+        if var is not None:
             self._putter.put_count += 1
             self._putter.putees.append(self)
         
     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()))
+        
+        if self._putter is not None:
+            putter_enabled = True
+            
+            if hasattr(self._putter.owner, 'enabled'):
+                putter_enabled = self._putter.owner.enabled
+                                
+            if putter_enabled:
+                if self._alt:
+                    alt = '*'
+                else:
+                    alt = ''
+    
+                # if something is being put to this 
+                rtn.append("put{alt} {comp} {param} ${value}".format(alt=alt, comp=self._component_name, param=self._parameter_name, value=self._putter.put_name()))
         
         return rtn
             
@@ -54,11 +68,22 @@ class putter(object):
     object.
     """
     
-    def __init__(self, put_name, isPutter=True):
+    def __init__(self, put_name, owner, isPutter=True):
         self._put_name = put_name
         self.put_count = 0
         self._isPutter = isPutter
         self.putees = [] # list of params that this puts to
+        self.__owner = owner
+        assert(owner is not None)
+    
+    @property
+    def owner(self): return self.__owner
+    
+    @property
+    def name(self): return self._put_name
+    
+    @property
+    def putCount(self): return self.put_count
     
     @property
     def isPutter(self): return self._isPutter
diff --git a/work_in_progress/optivis_ex.py b/work_in_progress/optivis_ex.py
index a0806ee1153766503aa12d129b3f553aa12730e3..d291127588a872dc2af9783077db9b3bd383836e 100644
--- a/work_in_progress/optivis_ex.py
+++ b/work_in_progress/optivis_ex.py
@@ -22,6 +22,7 @@ attr m1 Rc -500
 attr m2 Rc 500
 cav c1 m1 n4b m2 n7a
 
+pd P n5b
 maxtem 0
 noxaxis
 """)