diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e3843f1983639a2d060539b117f8ebc3c22756dd..bbaa78a4c9d18f6ea78e1c6e278b7f9f0e0c5856 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -42,9 +42,6 @@ basic-3.7:
 python-2.7:
   stage: test
   image: bilbydev/bilby-test-suite-python27
-  before_script:
-    # Install the dependencies specified in the Pipfile
-    - pipenv install --two --python=/opt/conda/bin/python2 --system --deploy
   script:
     - python setup.py install
     # Run tests without finding coverage
@@ -54,9 +51,6 @@ python-2.7:
 python-3.7:
   stage: test
   image: bilbydev/bilby-test-suite-python37
-  before_script:
-    # Install the dependencies specified in the Pipfile
-    - pipenv install --three --python=/opt/conda/bin/python --system --deploy
   script:
     - python setup.py install
 
diff --git a/bilby/core/result.py b/bilby/core/result.py
index fb26371cbb821fcc671cbb6783f003d97e165cf5..5dbb6fa89d76fccb933c2ff26652e3dbef76d41e 100644
--- a/bilby/core/result.py
+++ b/bilby/core/result.py
@@ -200,6 +200,8 @@ class Result(object):
             if len(dictionary) == 1 and 'data' in dictionary:
                 dictionary = dictionary['data']
             try:
+                if isinstance(dictionary.get('posterior', None), dict):
+                    dictionary['posterior'] = pd.DataFrame(dictionary['posterior'])
                 return cls(**dictionary)
             except TypeError as e:
                 raise IOError("Unable to load dictionary, error={}".format(e))
@@ -425,6 +427,9 @@ class Result(object):
                     json.dump(dictionary, file, indent=2, cls=BilbyJsonEncoder)
             elif extension == 'hdf5':
                 import deepdish
+                for key in dictionary:
+                    if isinstance(dictionary[key], pd.DataFrame):
+                        dictionary[key] = dictionary[key].to_dict()
                 deepdish.io.save(file_name, dictionary)
             else:
                 raise ValueError("Extension type {} not understood".format(extension))
diff --git a/bilby/gw/likelihood.py b/bilby/gw/likelihood.py
index 1ee33f0545438fea7596a19bbadf3ff1dab8e506..6da8c8363c1ea56b92ff3561a1afd3eab40f6dfe 100644
--- a/bilby/gw/likelihood.py
+++ b/bilby/gw/likelihood.py
@@ -1,5 +1,6 @@
 from __future__ import division
 
+import os
 import json
 
 import numpy as np
@@ -297,10 +298,62 @@ class GravitationalWaveTransient(likelihood.Likelihood):
             self._rho_mf_ref_array, self._rho_opt_ref_array,
             self._dist_margd_loglikelihood_array)
 
+    @property
+    def cached_lookup_table_filename(self):
+        dmin = self._distance_array[0]
+        dmax = self._distance_array[-1]
+        n = len(self._distance_array)
+        cached_lookup_table_filename = (
+            '.distance_marginalization_lookup_dmin{}_dmax{}_n{}_v1.npy'
+            .format(dmin, dmax, n))
+        return cached_lookup_table_filename
+
+    @property
+    def cached_lookup_table(self):
+        """ Reads in the cached lookup table
+
+        Returns
+        -------
+        cached_lookup_table: np.ndarray
+            Columns are _distance_array, distance_prior_array,
+            dist_marged_log_l_tc_array. This is only returned if the file
+            exists and the first two columns match the equivalent values
+            stored on disk.
+
+        """
+
+        if os.path.exists(self.cached_lookup_table_filename):
+            loaded_file = np.load(self.cached_lookup_table_filename)
+            if self._test_cached_lookup_table(loaded_file):
+                return loaded_file
+        else:
+            return None
+
+    @cached_lookup_table.setter
+    def cached_lookup_table(self, lookup_table):
+        np.save(self.cached_lookup_table_filename, lookup_table)
+
+    def _test_cached_lookup_table(self, lookup_table):
+        cond_a = np.all(self._distance_array == lookup_table[0])
+        cond_b = np.all(self.distance_prior_array == lookup_table[1])
+        if cond_a and cond_b:
+            return True
+
     def _create_lookup_table(self):
         """ Make the lookup table """
-        self.distance_prior_array = np.array([self.priors['luminosity_distance'].prob(distance)
-                                              for distance in self._distance_array])
+
+        self.distance_prior_array = np.array(
+            [self.priors['luminosity_distance'].prob(distance)
+             for distance in self._distance_array])
+
+        # Check if a cached lookup table exists in file
+        cached_lookup_table = self.cached_lookup_table
+        if cached_lookup_table is not None:
+            self._dist_margd_loglikelihood_array = cached_lookup_table[-1]
+            logger.info("Using the cached lookup table {}"
+                        .format(os.path.abspath(self.cached_lookup_table_filename)))
+            return
+
         logger.info('Building lookup table for distance marginalisation.')
 
         self._dist_margd_loglikelihood_array = np.zeros((400, 800))
@@ -317,6 +370,10 @@ class GravitationalWaveTransient(likelihood.Likelihood):
         log_norm = logsumexp(0. / self._distance_array - 0. / self._distance_array ** 2.,
                              b=self.distance_prior_array * self._delta_distance)
         self._dist_margd_loglikelihood_array -= log_norm
+        self.cached_lookup_table = np.array([
+            self._distance_array,
+            self.distance_prior_array,
+            self._dist_margd_loglikelihood_array])
 
     def _setup_phase_marginalization(self):
         self._bessel_function_interped = interp1d(
@@ -334,6 +391,14 @@ class GravitationalWaveTransient(likelihood.Likelihood):
         self.time_prior_array =\
             self.priors['geocent_time'].prob(self._times) * delta_tc
 
+    @property
+    def interferometers(self):
+        return self._interferometers
+
+    @interferometers.setter
+    def interferometers(self, interferometers):
+        self._interferometers = InterferometerList(interferometers)
+
 
 class BasicGravitationalWaveTransient(likelihood.Likelihood):
 
diff --git a/bilby/gw/utils.py b/bilby/gw/utils.py
index d52a1a43f2893a6d342d8e9c31859c548b8d75c8..b0959727f202d07e6e7e69b31030df485ee481d9 100644
--- a/bilby/gw/utils.py
+++ b/bilby/gw/utils.py
@@ -418,8 +418,10 @@ def read_frame_file(file_name, start_time, end_time, channel=None, buffer_time=0
 
     if loaded is False:
         ligo_channel_types = ['GDS-CALIB_STRAIN', 'DCS-CALIB_STRAIN_C01', 'DCS-CALIB_STRAIN_C02',
-                              'DCH-CLEAN_STRAIN_C02']
-        virgo_channel_types = ['Hrec_hoft_V1O2Repro2A_16384Hz', 'FAKE_h_16384Hz_4R']
+                              'DCH-CLEAN_STRAIN_C02', 'GWOSC-16KHZ_R1_STRAIN',
+                              'GWOSC-4KHZ_R1_STRAIN']
+        virgo_channel_types = ['Hrec_hoft_V1O2Repro2A_16384Hz', 'FAKE_h_16384Hz_4R',
+                               'GWOSC-16KHZ_R1_STRAIN', 'GWOSC-4KHZ_R1_STRAIN']
         channel_types = dict(H1=ligo_channel_types, L1=ligo_channel_types, V1=virgo_channel_types)
         for detector in channel_types.keys():
             for channel_type in channel_types[detector]:
diff --git a/test/gw_likelihood_test.py b/test/gw_likelihood_test.py
index 0dbfd147eb7b452114ed62b02f7cfe4ccca7c4c7..0811070fc161af2b8619d7c19ea9682860ccce00 100644
--- a/test/gw_likelihood_test.py
+++ b/test/gw_likelihood_test.py
@@ -134,6 +134,19 @@ class TestGWTransient(unittest.TestCase):
                    'priors={})'.format(self.interferometers, self.waveform_generator, False, False, False, self.prior)
         self.assertEqual(expected, repr(self.likelihood))
 
+    def test_interferometers_setting_list(self):
+        ifos = [bilby.gw.detector.get_empty_interferometer(name=name) for name in ['H1', 'L1']]
+        self.likelihood.interferometers = ifos
+        self.assertListEqual(bilby.gw.detector.InterferometerList(ifos), self.likelihood.interferometers)
+        self.assertTrue(type(self.likelihood.interferometers) == bilby.gw.detector.InterferometerList)
+
+    def test_interferometers_setting_interferometer_list(self):
+        ifos = bilby.gw.detector.InterferometerList([bilby.gw.detector.get_empty_interferometer(name=name)
+                                                     for name in ['H1', 'L1']])
+        self.likelihood.interferometers = ifos
+        self.assertListEqual(bilby.gw.detector.InterferometerList(ifos), self.likelihood.interferometers)
+        self.assertTrue(type(self.likelihood.interferometers) == bilby.gw.detector.InterferometerList)
+
 
 class TestTimeMarginalization(unittest.TestCase):
 
diff --git a/test/gw_source_test.py b/test/gw_source_test.py
index 4f8b6df627ef8024d2d6d416a3758d0f2f204a4e..9c4562ffb4f3b568fa17f3e669228a7e8d9a030a 100644
--- a/test/gw_source_test.py
+++ b/test/gw_source_test.py
@@ -41,12 +41,13 @@ class TestLalBBH(unittest.TestCase):
             bilby.gw.source.lal_binary_black_hole(
                 self.frequency_array, **self.parameters), dict)
 
-    def test_lal_bbh_works_with_time_domain_approximant(self):
-        self.waveform_kwargs['waveform_approximant'] = 'SEOBNRv3'
-        self.parameters.update(self.waveform_kwargs)
-        self.assertIsInstance(
-            bilby.gw.source.lal_binary_black_hole(
-                self.frequency_array, **self.parameters), dict)
+    # Removed due to issue with SimInspiralFD - see https://git.ligo.org/lscsoft/lalsuite/issues/153
+    # def test_lal_bbh_works_with_time_domain_approximant(self):
+    #     self.waveform_kwargs['waveform_approximant'] = 'SEOBNRv3'
+    #     self.parameters.update(self.waveform_kwargs)
+    #     self.assertIsInstance(
+    #         bilby.gw.source.lal_binary_black_hole(
+    #             self.frequency_array, **self.parameters), dict)
 
 
 class TestLalBNS(unittest.TestCase):
diff --git a/test/gw_utils_test.py b/test/gw_utils_test.py
index bce6f97de0978fff982b1ee65d59e0559a8cfeab..5d3ae04fa4e6fceb0d59f9b95b247c16c63260c7 100644
--- a/test/gw_utils_test.py
+++ b/test/gw_utils_test.py
@@ -162,7 +162,6 @@ class TestGWUtils(unittest.TestCase):
     def test_get_approximant(self):
         with self.assertRaises(ValueError):
             gwutils.lalsim_GetApproximantFromString(10)
-        self.assertEqual(gwutils.lalsim_GetApproximantFromString("IMRPhenomPV2"), 69)
 
     def test_lalsim_SimInspiralChooseFDWaveform(self):
         a = gwutils.lalsim_SimInspiralChooseFDWaveform(
diff --git a/test/result_test.py b/test/result_test.py
index 297d22b4e6f4360deffe6e670e93466f8c10f894..1d0dbefee70df890edbec43feb5be8eed3d496b5 100644
--- a/test/result_test.py
+++ b/test/result_test.py
@@ -283,8 +283,9 @@ class TestResult(unittest.TestCase):
         x = np.linspace(0, 1, 10)
         y = np.linspace(0, 1, 10)
 
-        def model(xx):
+        def model(xx, theta):
             return xx
+        self.result.posterior = pd.DataFrame(dict(theta=[1, 2, 3]))
         self.result.plot_with_data(model, x, y, ndraws=10)
         self.assertTrue(
             os.path.isfile('{}/{}_plot_with_data.png'.format(