diff --git a/bin/test_fsig.py b/bin/test_fsig.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e5b318d0d47161be5de3bac4828c8531c5decb4
--- /dev/null
+++ b/bin/test_fsig.py
@@ -0,0 +1,50 @@
+from pykat import finesse
+from pykat.detectors import *
+from pykat.components import *
+from pykat.commands import *
+from pykat.structs import *
+
+import numpy as np
+import pylab as pl
+
+code = """
+l l1 2 0 n1
+m m1 0.99 0.01 0 n1 n2
+s cav1 1200 n2 n3
+m m2 0.99 0.01 -0.1 n3 n4
+
+attr m2 m 1  # mech sus1
+
+ad up_refl 0 n1
+ad low_refl 0 n1
+
+qd refl_A 0 0 n1
+qd refl_Q 0 90 n1
+qd tran_A 0 0 n4
+qd tran_Q 0 90 n4
+
+put up_refl f $x1
+put low_refl f $mx1
+
+yaxis log re:im
+"""
+
+kat = finesse.kat(kat_code=code)
+
+kat.signals.apply(kat.l1.power, 1, 0)
+kat.signals.apply(kat.m1.phi, 1, 90)
+
+kat.add(xaxis('log', [1, 1000], kat.signals.f, 100))
+
+out = kat.run(printout=0, printerr=0)
+
+# using real and imag part compute the complex value of the upper and lower sidebands
+a_up = out.y[:,0] + out.y[:,1]*1j
+a_lo = out.y[:,2] + out.y[:,3]*-1j
+
+pl.figure(1)
+pl.loglog(out.x, np.abs(a_up + a_lo), out.x, np.abs((a_up - a_lo) / (1j)))
+pl.xlabel(out.xlabel)
+pl.title("Reflection quadratures with no relative carrier phase")
+pl.legend(["Amplitude","Phase"])
+pl.show()
\ No newline at end of file
diff --git a/pykat/commands.py b/pykat/commands.py
index 27a3bdad90adad26b3787863c88adb01b5d8a34c..a47b0dd0a51e6bb3573a579a933af2bf0b39cca7 100644
--- a/pykat/commands.py
+++ b/pykat/commands.py
@@ -10,6 +10,7 @@ import exceptions
 from components import *
 from structs import *
 from pykat.param import Param, putter
+import pykat.exceptions as pkex
 
 class Command(object):
     def __init__(self):
@@ -50,7 +51,7 @@ class gauss(object):
         
 class xaxis(Command):
 
-    def __init__(self, scale, limits, comp, param, steps, axis_type="xaxis"):
+    def __init__(self, scale, limits, param, steps, comp=None, axis_type="xaxis"):
         self._axis_type = axis_type
 
         self.x = putter("x1")
@@ -79,20 +80,17 @@ class xaxis(Command):
 
         self.steps = int(steps)
 
-        # if entered component is a string then just store and use that
-        if isinstance(comp, str):
-            self.__comp = comp
-        elif not isinstance(comp, Component):
-            raise exceptions.ValueError("{0} has not been added".format(comp))
-        else:
-            self.__comp = comp
-
         if isinstance(param, str):
             self.__param = param
+            if comp == None:
+                raise pkex.BasePyKatException("If parameter is set with a string, the comp argument must set the component name")
+                
+            self.__comp = comp
         elif not isinstance(param, Param) :
-            raise exceptions.ValueError("param argument is not of type Param")
+            raise pkex.BasePyKatException("param argument is not of type Param")
         else:
             self.__param = param
+            self.__comp = param._owner.name
 
     @staticmethod
     def parseFinesseText(text):
@@ -108,7 +106,7 @@ class xaxis(Command):
         if len(values) != 6:
             raise exceptions.RuntimeError("xaxis Finesse code format incorrect '{0}'".format(text))
 
-        return xaxis(values[2], [values[3], values[4]], values[0], values[1], values[5], axis_type=axis_type)
+        return xaxis(values[2], [values[3], values[4]], values[1], values[5], comp=values[0], axis_type=axis_type)
 
     def getFinesseText(self):
         # store either the component name of the string provided
@@ -120,8 +118,8 @@ class xaxis(Command):
                 min(self.limits), max(self.limits), self.steps, axis_type=self._axis_type);
 
 class x2axis(xaxis):
-    def __init__(self, scale, limits, comp, param, steps):
-        xaxis.__init__(self, scale, limits, comp, param, steps, axis_type="x2axis")
+    def __init__(self, scale, limits, param, steps, comp=None):
+        xaxis.__init__(self, scale, limits, param, steps, comp=comp, axis_type="x2axis")
         self.x = putter("x2")
         self.mx = putter("mx2")
 
diff --git a/pykat/components.py b/pykat/components.py
index 8a37f6f0dc12998dc789107c2ce6d2a6a3f260d9..696c42eeb5575cb0ce2b9ca42f1c38c87f4c5813 100644
--- a/pykat/components.py
+++ b/pykat/components.py
@@ -158,11 +158,11 @@ class AbstractMirrorComponent(Component):
 
         self.__R = Param("R", self, SIfloat(R))
         self.__T = Param("T", self, SIfloat(T))
-        self.__phi = Param("phi", self, SIfloat(phi))
+        self.__phi = Param("phi", self, SIfloat(phi), canFsig=True, fsig_name="phs")
         self.__Rcx = AttrParam("Rcx", self, SIfloat(Rcx))
         self.__Rcy = AttrParam("Rcy", self, SIfloat(Rcy))
-        self.__xbeta = AttrParam("xbeta", self, SIfloat(xbeta))
-        self.__ybeta = AttrParam("ybeta", self, SIfloat(ybeta))
+        self.__xbeta = AttrParam("xbeta", self, SIfloat(xbeta), canFsig=True, fsig_name="x")
+        self.__ybeta = AttrParam("ybeta", self, SIfloat(ybeta), canFsig=True, fsig_name="y")
         self.__mass = AttrParam("mass", self, SIfloat(mass))
         self.__r_ap = AttrParam("r_ap", self, SIfloat(r_ap))
         
@@ -682,9 +682,9 @@ class laser(Component):
         
         self._requested_node_names.append(node)
         
-        self.__power = Param("P", self, SIfloat(P))
-        self.__f_offset = Param("f", self, SIfloat(f_offset))
-        self.__phase = Param("phase", self, SIfloat(phase))
+        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.__phase = Param("phase", self, SIfloat(phase), canFsig=True, fsig_name="phs")
         self.__noise = AttrParam("noise", self, 0)
         
     @property
diff --git a/pykat/finesse.py b/pykat/finesse.py
index a40f85813920ef8dc4e5c006f4acac657d58c5e8..c94ef794149175dcd8c08d3bf5eaf7debc16406e 100644
--- a/pykat/finesse.py
+++ b/pykat/finesse.py
@@ -40,6 +40,7 @@ from pykat.components import Component
 from pykat.commands import Command, xaxis
 from pykat.gui.gui import pyKatGUI
 from pykat.SIfloat import *
+from pykat.param import Param, AttrParam
 
 import pykat.exceptions as pkex
 
@@ -127,7 +128,98 @@ class katRun2D(object):
             return self.z[idx].squeeze()
         else:
             raise  pkex.BasePyKatException("No output by the name {0} found".format(str(value)))
-      
+    
+class Signals:
+    class fsig:
+        def __init__(self, param, name, amplitude, phase):
+            self._params = []
+            self.__target = param
+            self.__name = name
+            self.__amplitude = Param("amp", self, SIfloat(amplitude))
+            self.__phase = Param("phase", self, SIfloat(phase))
+            
+            # unfortunatenly the target names for fsig are not the same as the
+            # various parameter names of the components, e.g. mirror xbeta is x 
+            # for fsig. So we need to check here what type of component we are targetting
+            # and then based on the parameter specfied get the name
+            if not param.canFsig:
+                raise  pkex.BasePyKatException("Cannot fsig parameter {1} on component {0}".format(str(param._owner), param.name))
+            
+            
+        def _register_param(self, param):
+            self._params.append(param)
+  
+        @property
+        def name(self): return self.__name
+
+        @property
+        def amplitude(self): return self.__amplitude
+
+        @property
+        def phase(self): return self.__phase
+
+        @property
+        def target(self): return self.__target.fsig_name
+
+        @property
+        def owner(self): return self.__target._owner.name
+    
+        def getFinesseText(self):
+            rtn = []
+    
+            for p in self._params:
+                rtn.extend(p.getFinesseText())
+        
+            return rtn
+    
+    @property
+    def name(self):
+        # if we don't have any signals yet then use a dummy name
+        # however we need to always tune a real fsig command
+        # so need to get the name of at least one of them
+        # as if you tune one you tune them all
+        if len(self.targets) == 0:
+            return "signal"
+        else:
+            return self.targets[0].name
+
+    @property
+    def f(self): return self.__f
+    
+    def __init__(self):
+
+        self.targets = []
+        self._params = []
+        
+        self.__f = Param("f", self, 1)
+    
+    def _register_param(self, param):
+        self._params.append(param)
+        
+    def apply(self, target, amplitude, phase, name=None):
+        
+        if target == None:
+            raise  pkex.BasePyKatException("No target was specified for signal to be applied")
+        
+        if name == None:
+            name = "sig_" +target._owner.name + "_" + target.name
+        
+        self.targets.append(Signals.fsig(target, name, amplitude, phase))
+        
+        
+    def getFinesseText(self):
+        rtn = []
+        
+        for t in self.targets:
+            rtn.extend(t.getFinesseText())
+            rtn.append("fsig {name} {comp} {target} {frequency} {phase} {amplitude}".format(name = t.name, comp=t.owner, target=t.target, frequency=str(self.f), phase=str(t.phase), amplitude=str(t.amplitude)))
+        
+        for p in self._params:
+            rtn.extend(p.getFinesseText())
+        
+        return rtn
+        
+        
 class Block:
     def __init__(self, name):
         self.__name = name
@@ -154,10 +246,11 @@ class kat(object):
         self.__tempdir = tempdir
         self.__tempname = tempname
         self.pykatgui = None
-
-	# initialise default block
-	self.__currentTag= NO_BLOCK
-	self.__blocks[NO_BLOCK] = Block(NO_BLOCK)
+        self.__signals = Signals()
+        
+        # initialise default block
+        self.__currentTag= NO_BLOCK
+        self.__blocks[NO_BLOCK] = Block(NO_BLOCK)
         
         # Various options for running finesse, typicaly the commands with just 1 input
         # and have no name attached to them.
@@ -181,6 +274,9 @@ class kat(object):
         cls = type(self)
         self.__class__ = type(cls.__name__, (cls,), {})
         
+    @property
+    def signals(self): return self.__signals
+
     @property
     def maxtem(self): return self.__maxtem
     @maxtem.setter
@@ -689,6 +785,16 @@ class kat(object):
                     out.append(txt + "\n")
         
 
+        # now get any signal commands
+        txt = self.signals.getFinesseText()
+        
+        if txt != None:
+            if isinstance(txt,list):
+                for t in txt: out.append(t+ "\n")
+            else:
+                out.append(txt + "\n")
+                            
+
         if self.scale != None and self.scale !='': out.append("scale {0}\n".format(self.scale))
         if self.phase != None: out.append("phase {0}\n".format(self.phase))
         if self.maxtem != None: out.append("maxtem {0}\n".format(self.maxtem))            
diff --git a/pykat/param.py b/pykat/param.py
index e47d378b248c218aef32e905d24df4f17a838ae7..52a5fc88554f8ce86990f5d672a8ec652fd65c09 100644
--- a/pykat/param.py
+++ b/pykat/param.py
@@ -57,13 +57,22 @@ class putter(object):
         
 class Param(putable, putter):
 
-    def __init__(self, name, owner, value, isPutable=True, isPutter=True, isTunable=True, var_name=None):
+    def __init__(self, name, owner, value, canFsig=False, fsig_name=None, isPutable=True, isPutter=True, isTunable=True, var_name=None):
         self._name = name
         self._owner = owner
         self._value = value
         self._isPutter = isPutter
         self._isTunable = isTunable
         self._owner._register_param(self)
+        self._canFsig = False
+        
+        if canFsig:
+            self._canFsig = True
+
+            if fsig_name == None:
+                raise pkex.BasePyKatException("If parameter is a possible fsig target the fsig_name argument must be set")
+
+            self.__fsig_name = fsig_name
         
         if isPutter:
             if var_name == None:
@@ -73,7 +82,13 @@ class Param(putable, putter):
             
         if isPutable:
             putable.__init__(self, owner.name, name, isPutable)
-        
+    
+    @property
+    def canFsig(self): return self._canFsig
+    
+    @property
+    def fsig_name(self): return self.__fsig_name
+    
     @property
     def name(self): return self._name