diff --git a/tests/test_transform.py b/tests/test_transform.py
index 709337990997080288c8df10797b33c06936280c..6d1991adb4e30617ff217232defba61040a072ee 100644
--- a/tests/test_transform.py
+++ b/tests/test_transform.py
@@ -5,43 +5,116 @@
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
 
+import os.path as op
+
 import numpy as np
-import numpy.linalg as npla
 
 import fsl.utils.transform as transform
 
+
+datadir = op.join(op.dirname(__file__), 'testdata')
+
+
+def readlines(filename):
+    with open(filename, 'rt') as f:
+        lines = f.readlines()
+        lines = [l.strip() for l in lines]
+        lines = [l         for l in lines if not l.startswith('#')]
+        lines = [l         for l in lines if l != '']
+    return lines
+
+
+def test_invert():
+
+    testfile = op.join(datadir, 'test_transform_test_invert.txt')
+    testdata = np.loadtxt(testfile)
+
+    nmatrices = testdata.shape[0] / 4
+
+    for i in range(nmatrices):
+
+        x      = testdata[i * 4:i * 4 + 4, 0:4]
+        invx   = testdata[i * 4:i * 4 + 4, 4:8]
+        result = transform.invert(x)
+
+        assert np.all(np.isclose(invx, result))
+
+
+def test_concat():
+    
+    testfile = op.join(datadir, 'test_transform_test_concat.txt')
+    lines    = readlines(testfile)
+
+
+    ntests = len(lines) / 4
+    tests  = []
+
+    for i in range(ntests):
+        ilines = lines[i * 4:i * 4 + 4]
+
+        data    = np.genfromtxt(ilines)
+        ninputs = data.shape[1] / 4 - 1
+
+        inputs  = []
+
+        for j in range(ninputs):
+            inputs.append(data[:, j * 4:j * 4 + 4])
+
+        output = data[:, -4:]
+
+        tests.append((inputs, output))
+
+    for inputs, expected in tests:
+
+        result = transform.concat(*inputs)
+
+        assert np.all(np.isclose(result, expected))
+
+
 def test_scaleOffsetXform():
 
-    scales  = [1, 2, 3]
-    offsets = [4, 5, 6]
+    testfile = op.join(datadir, 'test_transform_test_scaleoffsetxform.txt')
+    lines    = readlines(testfile)
+    ntests   = len(lines) / 5
 
-    expected       = np.eye(4)
-    expected[0, 0] = scales[ 0]
-    expected[1, 1] = scales[ 1]
-    expected[2, 2] = scales[ 2]
-    expected[0, 3] = offsets[0]
-    expected[1, 3] = offsets[1]
-    expected[2, 3] = offsets[2]
+    for i in range(ntests):
+        
+        lineoff         = i * 5
+        scales, offsets = lines[lineoff].split(',')
 
-    generated = transform.scaleOffsetXform(scales, offsets) 
+        scales  = [float(s) for s in scales .split()]
+        offsets = [float(o) for o in offsets.split()]
 
-    assert np.all(np.isclose(expected, generated))
+        expected = lines[lineoff + 1: lineoff + 5]
+        expected = [[float(v) for v in l.split()] for l in expected]
+        expected = np.array(expected)
 
+        result = transform.scaleOffsetXform(scales, offsets)
 
-    scale  = 5
-    offset = 3
+        assert np.all(np.isclose(result, expected))
 
-    expected       = np.eye(4)
-    expected[0, 0] = scale
-    expected[1, 1] = 1
-    expected[2, 2] = 1
-    expected[2, 2] = 1
-    expected[0, 3] = offset
 
-    generated = transform.scaleOffsetXform(scale, offset)
-    assert np.all(np.isclose(expected, generated))
+def test_compose_and_decompose():
 
+    testfile = op.join(datadir, 'test_transform_test_compose.txt')
+    lines    = readlines(testfile)
+    ntests   = len(lines) / 4
 
-def test_invert():
+    for i in range(ntests):
+
+        xform                      = lines[i * 4: i * 4 + 4]
+        xform                      = np.genfromtxt(xform)
+        
+        scales, offsets, rotations = transform.decompose(xform)
+        result = transform.compose(scales, offsets, rotations)
+
+        assert np.all(np.isclose(xform, result))
+
+        # The decompose function does not support a
+        # different rotation origin, but we test
+        # explicitly passing the origin for
+        # completeness
+        scales, offsets, rotations = transform.decompose(xform)
+        result = transform.compose(scales, offsets, rotations, [0, 0, 0])
 
-    pass
+        assert np.all(np.isclose(xform, result))
diff --git a/tests/testdata/test_transform_test_compose.txt b/tests/testdata/test_transform_test_compose.txt
new file mode 100644
index 0000000000000000000000000000000000000000..28161a926d99eddb164ed600677c19491075879e
--- /dev/null
+++ b/tests/testdata/test_transform_test_compose.txt
@@ -0,0 +1,66 @@
+# Test data for test_transform:test_compose.
+#
+# Each test is just an affine transformation matrix.
+# The matrix is decomposed into its components,
+# and then recomposed, and the result compared with
+# the input.
+
+1.0  0.0  0.0  0.0
+0.0  1.0  0.0  0.0
+0.0  0.0  1.0  0.0
+0.0  0.0  0.0  1.0
+
+
+-1.0  0.0  0.0  0.0
+0.0   1.0  0.0  0.0
+0.0   0.0  1.0  0.0
+0.0   0.0  0.0  1.0
+
+1.0   0.0  0.0  0.0
+0.0  -1.0  0.0  0.0
+0.0   0.0  1.0  0.0
+0.0   0.0  0.0  1.0
+
+1.0  0.0   0.0  0.0
+0.0  1.0   0.0  0.0
+0.0  0.0  -1.0  0.0
+0.0  0.0   0.0  1.0 
+
+0.5   0.0  0.0   0.0
+0.0   2.4  0.0   0.0
+0.0   0.0  1.6   0.0
+0.0   0.0  0.0   1.0
+
+0.5   0.0   0.0  10.0
+0.0   2.4   0.0 -25.0
+0.0   0.0   1.6  53.0
+0.0   0.0   0.0   1.0
+
+0.5            0.0            0.0           10.0         
+0.0            0.0           -1.6           -6.7877502441
+0.0            2.4            0.0           29.7931518555
+0.0            0.0            0.0            1.0         
+
+0.0           -2.4           -0.0           30.6160888672
+0.0            0.0           -1.6           -6.7877502441
+0.5            0.0            0.0           50.5961608887
+0.0            0.0            0.0            1.0         
+
+-0.0            1.3765834472   1.3106432709   0.0736983719
+ 0.0           -1.9659649063   0.9177222982  14.1062102814
+ 0.5            0.0            0.0           50.5961608887
+ 0.0            0.0            0.0            1.0
+
+ 0.453766452   -0.7004337463   0.4832135801  16.789591468 
+-0.0159784155   1.6056689296   1.1880787388 -16.2943532298
+-0.2093817023  -1.640493784    0.9565424959  66.1123321137
+ 0.0            0.0            0.0            1.0
+ 
+-1.1974397443   -0.8580717933   -0.3645386503  -50.0240993667
+-0.7458801726    1.1196201539   -0.5710576979 -106.3700007704
+ 0.7128023509   -0.2699020211   -1.2099478647   -7.4191935569
+ 0.0             0.0             0.0             1.0
+
+
+
+
diff --git a/tests/testdata/test_transform_test_concat.txt b/tests/testdata/test_transform_test_concat.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6218eec65a80fce0c6137aa3b936844b866bcf98
--- /dev/null
+++ b/tests/testdata/test_transform_test_concat.txt
@@ -0,0 +1,55 @@
+# Test data for test_transform:test_concat.
+#
+# Each set of four lines contains a set of 4x4
+# matrices to be concatenated (in order). The
+# last matrix of each set is the expected result.
+
+1 0 0 0 1 0 0 0
+0 1 0 0 0 1 0 0
+0 0 1 0 0 0 1 0
+0 0 0 1 0 0 0 1
+
+1 0 0 0 1 0 0 0 1 0 0 0
+0 1 0 0 0 1 0 0 0 1 0 0
+0 0 1 0 0 0 1 0 0 0 1 0
+0 0 0 1 0 0 0 1 0 0 0 1
+
+1 0 0 0 2 0 0 0 2 0 0 0
+0 1 0 0 0 1 0 0 0 1 0 0
+0 0 1 0 0 0 1 0 0 0 1 0
+0 0 0 1 0 0 0 1 0 0 0 1
+
+1 0 0 0 2 0 0 0 2 0 0 0
+0 2 0 0 0 1 0 0 0 2 0 0
+0 0 1 0 0 0 1 0 0 0 1 0
+0 0 0 1 0 0 0 1 0 0 0 1
+
+1 0 0   0 2 0 0 0 2 0 0 0
+0 2 0   0 0 1 0 0 0 2 0 0
+0 0 0.5 0 0 0 2 0 0 0 1 0
+0 0 0   1 0 0 0 1 0 0 0 1
+
+1 0 0 5 1 0 0 5 1 0 0 10
+0 1 0 0 0 1 0 0 0 1 0 0
+0 0 1 0 0 0 1 0 0 0 1 0
+0 0 0 1 0 0 0 1 0 0 0 1
+
+1 0 0  5  1 0 0   5  1 0 0  10
+0 1 0 10  0 1 0 -11  0 1 0 -1
+0 0 1  0  0 0 1   0  0 0 1  0
+0 0 0  1  0 0 0   1  0 0 0  1
+
+-0.9997461427  -0.0138411649  -0.0177840895  86.2687562744 0.4995293021  -0.0288470406  -0.0208370071  -52.4121894836  -0.4998648078    0.018194362     0.0057373182  141.0497999726
+-0.0129887148   0.9988017675  -0.0471861176  78.2934660214 0.0181582421   0.8188890815   0.0380228758  -79.7248840332   0.0110884427    0.8201107175   -0.0004052935    2.7375548032
+-0.0184158914   0.0469431359   0.9987278995  79.2867553867 0.0118636154  -0.0387438014   0.8191658258  -71.8998947144   0.0035016511    0.00027795      0.8202924096    4.7010056936
+ 0.0            0.0            0.0            1.0          0.0            0.0            0.0             1.0            0.0             0.0             0.0             1.0
+
+-2.0  0.0  0.0   90.0  0.5  0.0  0.0  0.0 1.099592034   -0.0201869499  -0.0383800223 -13.9469605   3.0  0.0  0.0  0.0  -3.298776102     0.0605608496    0.1343300781  103.9469605   
+ 0.0  2.0  0.0 -126.0  0.0  0.5  0.0  0.0 0.0351074645   0.9816051002   0.1625775275   7.338456156 0.0  3.0  0.0  0.0   0.1053223934    2.9448153006    0.5690213463 -118.661543844 
+ 0.0  0.0  2.0  -72.0  0.0  0.0  0.5  0.0 0.056531896   -0.1960538631   1.18656088    29.70779308  0.0  0.0  3.5  0.0   0.1695956881   -0.5881615893    4.15296308    -42.29220692  
+ 0.0  0.0  0.0    1.0  0.0  0.0  0.0  1.0 0.0            0.0            0.0            1.0         0.0  0.0  0.0  1.0   0.0             0.0             0.0             1.0         
+
+0.5  0.0  0.0  0.0  -2.0  -0.0  -0.0 180.0  -1.0697441868    0.0             0.0            98.5041786294  1.0 0.0 0.0 0.0  1.0697441868  0.0           0.0          -8.5041786294
+0.0  0.5  0.0  0.0   0.0   2.0   0.0 252.0   0.0             1.0030898154    0.223667641  -133.9357410938  0.0 1.0 0.0 0.0  0.0           1.0030898154  0.223667641  -7.9357410938
+0.0  0.0  0.5  0.0   0.0   0.0   2.0 144.0   0.0            -0.202107448     1.1100963122  -77.9863761881  0.0 0.0 1.0 0.0  0.0          -0.202107448   1.1100963122 -5.9863761881
+0.0  0.0  0.0  1.0   0.0   0.0   0.0   1.0   0.0             0.0             0.0             1.0           0.0 0.0 0.0 1.0  0.0           0.0           0.0           1.0         
diff --git a/tests/testdata/test_transform_test_invert.txt b/tests/testdata/test_transform_test_invert.txt
new file mode 100644
index 0000000000000000000000000000000000000000..21c3251c2bb8d60ac798904d55133a3a4d11f2a6
--- /dev/null
+++ b/tests/testdata/test_transform_test_invert.txt
@@ -0,0 +1,64 @@
+# Test data for test_transform:test_invert.
+#
+# Pairs of 4x4 matrices - columns 0-3 are 
+# the matrix, and 4-7 are its inverse
+
+1.0 0.0 0.0 0.0   1.0 0.0 0.0 0.0
+0.0 1.0 0.0 0.0   0.0 1.0 0.0 0.0
+0.0 0.0 1.0 0.0   0.0 0.0 1.0 0.0
+0.0 0.0 0.0 1.0   0.0 0.0 0.0 1.0
+ 
+2.0 0.0 0.0 0.0   0.5 0.0 0.0 0.0
+0.0 2.0 0.0 0.0   0.0 0.5 0.0 0.0
+0.0 0.0 2.0 0.0   0.0 0.0 0.5 0.0
+0.0 0.0 0.0 1.0   0.0 0.0 0.0 1.0
+
+0.5 0.0 0.0 0.0   2.0 0.0 0.0 0.0
+0.0 0.5 0.0 0.0   0.0 2.0 0.0 0.0
+0.0 0.0 0.5 0.0   0.0 0.0 2.0 0.0
+0.0 0.0 0.0 1.0   0.0 0.0 0.0 1.0
+ 
+-2.0 0.0 0.0   90.0  -0.5 0.0 0.0 45.0
+ 0.0 2.0 0.0 -126.0   0.0 0.5 0.0 63.0
+ 0.0 0.0 2.0  -72.0   0.0 0.0 0.5 36.0
+ 0.0 0.0 0.0    1.0   0.0 0.0 0.0  1.0
+
+-1.000000  0.000000  0.000000    90.000000 -1.0   -0.0   -0.0   90.0
+ 0.000000  1.000000  0.000000  -126.000000  0.0    1.0    0.0  126.0
+ 0.000000  0.000000  1.000000   -72.000000  0.0    0.0    1.0   72.0
+ 0.000000  0.000000  0.000000     1.000000  0.0    0.0    0.0    1.0
+
+-0.500000  0.000000  -0.000000    90.000000 -2.0   -0.0   -0.0  180.0
+ 0.000000  0.500000  -0.000000  -126.000000  0.0    2.0    0.0  252.0
+ 0.000000  0.000000  0.500000    -72.000000  0.0    0.0    2.0  144.0
+ 0.000000  0.000000  0.000000      1.000000  0.0    0.0    0.0    1.0
+
+-0.998351  0.172174 -0.001494   88.454048 -0.9983502856   0.0558051012   0.0134829296  94.7258462378 
+ 0.055805  2.891963 -0.260024  -92.767029  0.0191304269   0.3213296014   0.0865595511  36.0827985889 
+ 0.013483  0.779035  0.965601  -92.031090 -0.001493904   -0.2600239915   0.9656009985  64.8758010985 
+ 0.000000  0.000000  0.000000    1.000000  0.0            0.0            0.0            1.0
+ 
+-0.374721  0.013086  0.098275    97.767311 -2.66468674      0.0722679469    0.0731063439  275.2545057881
+ 0.010162  0.351788 -2.071789  -111.735596  0.093050276     2.5016056231    0.9189276383  354.1399342608
+ 0.010280  0.129224  5.630100   -91.104904  0.0027297296   -0.0575496704    0.1563917091    7.5508265955
+ 0.000000  0.000000  0.000000     1.000000  0.0             0.0             0.0             1.0
+
+-0.388466  -0.008614  -0.667304  102.035919  -2.5458450588    0.2688093573   -0.0000011573  240.3890243945
+ 0.041017  -0.081580  -6.319922   72.090378  -0.0564513141   -0.5346421283    2.502913283   147.3211514593
+-0.000000   0.381914  -1.365036  -41.159451  -0.0157941235   -0.1495838306   -0.0323085812   11.0653193311
+ 0.000000   0.000000   0.000000    1.000000   0.0             0.0             0.0             1.0         
+
+ 0.187901   0.567822  -0.807414   301.810486  0.187902    0.515238    0.836195 -331.561887
+ 0.515238   0.376990   0.874776  -291.188751  0.955833    0.634599   -0.605804  204.125469
+ 0.836196  -0.359885  -0.357576   508.114258 -0.522595    0.566194   -0.231439  440.191288
+ 0.000000   0.000000   0.000000     1.000000  0.0         0.0         0.0         1.0 
+
+-2.000000  0.000000  -0.000000  90.000000  -0.5  -0.0  -0.0  45.0
+ 0.000000  0.000000  -2.000000  90.000000   0.0   0.0   0.5  36.0
+ 0.000000  2.000000  -0.000000 -72.000000  -0.0  -0.5  -0.0  45.0
+ 0.000000  0.000000   0.000000   1.000000   0.0   0.0   0.0   1.0
+
+ 1.912642  0.560466  0.166370 -120.273781 0.4781604465   0.0748382388  -0.125546007   48.6068918211
+ 0.299353 -0.449972 -1.925594   92.759918 0.1401164411  -0.1124929472   0.4665968825  34.5763635373
+-0.502184  1.866388 -0.514206  -15.622035 0.0415925106  -0.4813986086  -0.1285515567  47.6487470535
+ 0.000000  0.000000  0.000000    1.000000 0.0            0.0            0.0            1.0
diff --git a/tests/testdata/test_transform_test_scaleoffsetxform.txt b/tests/testdata/test_transform_test_scaleoffsetxform.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b5b0944060425167784712df6b9489b1e0380a59
--- /dev/null
+++ b/tests/testdata/test_transform_test_scaleoffsetxform.txt
@@ -0,0 +1,54 @@
+# Test data for test_transform:test_scaleOffsetXform.
+#
+# The first line specifies the scale and 
+# offset parameters (separated with a comma).
+# This is followed by the expected
+# 
+# 
+1, 0
+1 0 0 0
+0 1 0 0
+0 0 1 0
+0 0 0 1
+
+1 1, 0
+1 0 0 0
+0 1 0 0
+0 0 1 0
+0 0 0 1
+
+1 1 1, 0
+1 0 0 0
+0 1 0 0
+0 0 1 0
+0 0 0 1
+
+1, 1
+1 0 0 1
+0 1 0 0
+0 0 1 0
+0 0 0 1
+
+1 1, 1 1
+1 0 0 1
+0 1 0 1
+0 0 1 0
+0 0 0 1
+
+1 1 1, 1 1 1
+1 0 0 1
+0 1 0 1
+0 0 1 1
+0 0 0 1
+
+1 2 3, 4 5 6
+1 0 0 4
+0 2 0 5
+0 0 3 6
+0 0 0 1
+
+1 10, 20 5 5
+1 0  0 20
+0 10 0 5
+0 0  1 5
+0 0  0 1