diff --git a/bilby/core/prior/base.py b/bilby/core/prior/base.py
index db5880da1a3cf77e67aff29fe9a8bdf2f2e69892..802d5f6f12f0ed15e44b76514809832c406f16f3 100644
--- a/bilby/core/prior/base.py
+++ b/bilby/core/prior/base.py
@@ -68,6 +68,9 @@ class Prior(object):
         if sorted(self.__dict__.keys()) != sorted(other.__dict__.keys()):
             return False
         for key in self.__dict__:
+            if key == "least_recently_sampled":
+                # ignore sample drawn from prior in comparison
+                continue
             if type(self.__dict__[key]) is np.ndarray:
                 if not np.array_equal(self.__dict__[key], other.__dict__[key]):
                     return False
diff --git a/bilby/core/result.py b/bilby/core/result.py
index d967138c77ba014af15f5ebc26e6338b6afcaafb..96432e066e99acd63f78ce7b28fb16debe417b33 100644
--- a/bilby/core/result.py
+++ b/bilby/core/result.py
@@ -23,7 +23,8 @@ from .utils import (
     check_directory_exists_and_if_not_mkdir,
     latex_plot_format, safe_save_figure,
     BilbyJsonEncoder, load_json,
-    move_old_file, get_version_information
+    move_old_file, get_version_information,
+    decode_bilby_json,
 )
 from .prior import Prior, PriorDict, DeltaFunction
 
@@ -358,10 +359,27 @@ class Result(object):
 
         if os.path.isfile(filename):
             dictionary = deepdish.io.load(filename)
-            # Some versions of deepdish/pytables return the dictionanary as
+            # Some versions of deepdish/pytables return the dictionary as
             # a dictionary with a key 'data'
             if len(dictionary) == 1 and 'data' in dictionary:
                 dictionary = dictionary['data']
+
+            if "priors" in dictionary:
+                # parse priors from JSON string (allowing for backwards
+                # compatibility)
+                if not isinstance(dictionary["priors"], PriorDict):
+                    try:
+                        priordict = PriorDict()
+                        for key, value in dictionary["priors"].items():
+                            if key not in ["__module__", "__name__", "__prior_dict__"]:
+                                priordict[key] = decode_bilby_json(value)
+                        dictionary["priors"] = priordict
+                    except Exception as e:
+                        raise IOError(
+                            "Unable to parse priors from '{}':\n{}".format(
+                                filename, e,
+                            )
+                        )
             try:
                 if isinstance(dictionary.get('posterior', None), dict):
                     dictionary['posterior'] = pd.DataFrame(dictionary['posterior'])
@@ -609,8 +627,9 @@ class Result(object):
                     dictionary['sampler_kwargs'][key] = str(dictionary['sampler_kwargs'])
 
         try:
+            # convert priors to JSON dictionary for both JSON and hdf5 files
+            dictionary["priors"] = dictionary["priors"]._get_json_dict()
             if extension == 'json':
-                dictionary["priors"] = dictionary["priors"]._get_json_dict()
                 if gzip:
                     import gzip
                     # encode to a string
diff --git a/bilby/core/sampler/base_sampler.py b/bilby/core/sampler/base_sampler.py
index 2ae872b33383f03c13756fe89c62ca79a8372ce1..74e880fbb852ac48ecde433bcbc0d54de2115b5d 100644
--- a/bilby/core/sampler/base_sampler.py
+++ b/bilby/core/sampler/base_sampler.py
@@ -430,6 +430,7 @@ class Sampler(object):
             likelihood evaluations.
 
         """
+        logger.info("Generating initial points from the prior")
         unit_cube = []
         parameters = []
         likelihood = []
diff --git a/bilby/core/sampler/dynesty.py b/bilby/core/sampler/dynesty.py
index a89e8f55a94096d2e0b4769a68d840e67c381f1e..cdf5846409df229728c2f33161ff5823dd325af5 100644
--- a/bilby/core/sampler/dynesty.py
+++ b/bilby/core/sampler/dynesty.py
@@ -257,11 +257,11 @@ class Dynesty(NestedSampler):
         # Constructing output.
         string = []
         string.append("bound:{:d}".format(bounditer))
-        string.append("nc:{:d}".format(nc))
-        string.append("ncall:{:d}".format(ncall))
+        string.append("nc:{:3d}".format(nc))
+        string.append("ncall:{:.1e}".format(ncall))
         string.append("eff:{:0.1f}%".format(eff))
         string.append("{}={:0.2f}+/-{:0.2f}".format(key, logz, logzerr))
-        string.append("dlogz:{:0.3f}>{:0.2f}".format(delta_logz, dlogz))
+        string.append("dlogz:{:0.3f}>{:0.2g}".format(delta_logz, dlogz))
 
         self.pbar.set_postfix_str(" ".join(string), refresh=False)
         self.pbar.update(niter - self.pbar.n)
@@ -793,7 +793,7 @@ def sample_rwalk_bilby(args):
         v = v_list[idx]
         logl = logl_list[idx]
     else:
-        logger.warning("Unable to find a new point using walk: returning a random point")
+        logger.debug("Unable to find a new point using walk: returning a random point")
         u = np.random.uniform(size=n)
         v = prior_transform(u)
         logl = loglikelihood(v)
diff --git a/bilby/core/sampler/ptemcee.py b/bilby/core/sampler/ptemcee.py
index 7baa0a9a65ffce828aab4ef19b7b725130787380..da13250a48b46a2fc45dffa375bfb8594a924c8f 100644
--- a/bilby/core/sampler/ptemcee.py
+++ b/bilby/core/sampler/ptemcee.py
@@ -193,7 +193,13 @@ class Ptemcee(MCMCSampler):
         )
         self.convergence_inputs = ConvergenceInputs(**convergence_inputs_dict)
 
-        # MultiProcessing inputs
+        # Check if threads was given as an equivalent arg
+        if threads == 1:
+            for equiv in self.npool_equiv_kwargs:
+                if equiv in kwargs:
+                    threads = kwargs.pop(equiv)
+
+        # Store threads
         self.threads = threads
 
         # Misc inputs
@@ -221,10 +227,6 @@ class Ptemcee(MCMCSampler):
             for equiv in self.nwalkers_equiv_kwargs:
                 if equiv in kwargs:
                     kwargs["nwalkers"] = kwargs.pop(equiv)
-        if "threads" not in kwargs:
-            for equiv in self.npool_equiv_kwargs:
-                if equiv in kwargs:
-                    kwargs["threads"] = kwargs.pop(equiv)
 
     def get_pos0_from_prior(self):
         """ Draw the initial positions from the prior
diff --git a/bilby/core/sampler/pymultinest.py b/bilby/core/sampler/pymultinest.py
index 055d4e14ad969f70da745fa13571db693405784a..9421c8207c09dae938d4b37cf6b61a46c2853a42 100644
--- a/bilby/core/sampler/pymultinest.py
+++ b/bilby/core/sampler/pymultinest.py
@@ -2,7 +2,10 @@ import importlib
 import os
 import tempfile
 import shutil
+import distutils.dir_util
 import signal
+import time
+import datetime
 
 import numpy as np
 
@@ -115,8 +118,15 @@ class Pymultinest(NestedSampler):
         # for PyMultiNest >=2.9 the n_params kwarg cannot be None
         if self.kwargs["n_params"] is None:
             self.kwargs["n_params"] = self.ndim
+        if self.kwargs['dump_callback'] is None:
+            self.kwargs['dump_callback'] = self._dump_callback
         NestedSampler._verify_kwargs_against_default_kwargs(self)
 
+    def _dump_callback(self, *args, **kwargs):
+        if self.use_temporary_directory:
+            self._copy_temporary_directory_contents_to_proper_path()
+        self._calculate_and_save_sampling_time()
+
     def _apply_multinest_boundaries(self):
         if self.kwargs["wrapped_params"] is None:
             self.kwargs["wrapped_params"] = []
@@ -154,10 +164,6 @@ class Pymultinest(NestedSampler):
             shutil.copytree(
                 self.outputfiles_basename, self.temporary_outputfiles_basename
             )
-            if os.path.islink(self.outputfiles_basename):
-                os.unlink(self.outputfiles_basename)
-            else:
-                shutil.rmtree(self.outputfiles_basename)
 
     def write_current_state_and_exit(self, signum=None, frame=None):
         """ Write current state and exit on exit_code """
@@ -166,15 +172,15 @@ class Pymultinest(NestedSampler):
                 signum, self.exit_code
             )
         )
+        self._calculate_and_save_sampling_time()
         if self.use_temporary_directory:
             self._move_temporary_directory_to_proper_path()
         os._exit(self.exit_code)
 
-    def _move_temporary_directory_to_proper_path(self):
+    def _copy_temporary_directory_contents_to_proper_path(self):
         """
-        Move the temporary back to the proper path
-
-        Anything in the proper path at this point is removed including links
+        Copy the temporary back to the proper path.
+        Do not delete the temporary directory.
         """
         logger.info(
             "Overwriting {} with {}".format(
@@ -185,11 +191,16 @@ class Pymultinest(NestedSampler):
             outputfiles_basename_stripped = self.outputfiles_basename[:-1]
         else:
             outputfiles_basename_stripped = self.outputfiles_basename
-        if os.path.islink(outputfiles_basename_stripped):
-            os.unlink(outputfiles_basename_stripped)
-        elif os.path.isdir(outputfiles_basename_stripped):
-            shutil.rmtree(outputfiles_basename_stripped)
-        shutil.move(self.temporary_outputfiles_basename, outputfiles_basename_stripped)
+        distutils.dir_util.copy_tree(self.temporary_outputfiles_basename, outputfiles_basename_stripped)
+
+    def _move_temporary_directory_to_proper_path(self):
+        """
+        Copy the temporary back to the proper path
+
+        Anything in the temporary directory at this point is removed
+        """
+        self._copy_temporary_directory_contents_to_proper_path()
+        shutil.rmtree(self.temporary_outputfiles_basename)
 
     def run_sampler(self):
         import pymultinest
@@ -197,17 +208,20 @@ class Pymultinest(NestedSampler):
         self._verify_kwargs_against_default_kwargs()
 
         self._setup_run_directory()
+        self._check_and_load_sampling_time_file()
 
         # Overwrite pymultinest's signal handling function
         pm_run = importlib.import_module("pymultinest.run")
         pm_run.interrupt_handler = self.write_current_state_and_exit
 
+        self.start_time = time.time()
         out = pymultinest.solve(
             LogLikelihood=self.log_likelihood,
             Prior=self.prior_transform,
             n_dims=self.ndim,
             **self.kwargs
         )
+        self._calculate_and_save_sampling_time()
 
         self._clean_up_run_directory()
 
@@ -222,26 +236,22 @@ class Pymultinest(NestedSampler):
         self.result.log_evidence_err = out["logZerr"]
         self.calc_likelihood_count()
         self.result.outputfiles_basename = self.outputfiles_basename
+        self.result.sampling_time = datetime.timedelta(seconds=self.total_sampling_time)
         return self.result
 
     def _setup_run_directory(self):
         """
         If using a temporary directory, the output directory is moved to the
-        temporary directory and symlinked back.
+        temporary directory.
         """
         if self.use_temporary_directory:
             temporary_outputfiles_basename = tempfile.TemporaryDirectory().name
             self.temporary_outputfiles_basename = temporary_outputfiles_basename
 
             if os.path.exists(self.outputfiles_basename):
-                shutil.move(self.outputfiles_basename, self.temporary_outputfiles_basename)
+                distutils.dir_util.copy_tree(self.outputfiles_basename, self.temporary_outputfiles_basename)
             check_directory_exists_and_if_not_mkdir(temporary_outputfiles_basename)
 
-            os.symlink(
-                os.path.abspath(self.temporary_outputfiles_basename),
-                os.path.abspath(self.outputfiles_basename),
-                target_is_directory=True,
-            )
             self.kwargs["outputfiles_basename"] = self.temporary_outputfiles_basename
             logger.info("Using temporary file {}".format(temporary_outputfiles_basename))
         else:
@@ -249,6 +259,21 @@ class Pymultinest(NestedSampler):
             self.kwargs["outputfiles_basename"] = self.outputfiles_basename
             logger.info("Using output file {}".format(self.outputfiles_basename))
 
+    def _check_and_load_sampling_time_file(self):
+        self.time_file_path = self.kwargs["outputfiles_basename"] + '/sampling_time.dat'
+        if os.path.exists(self.time_file_path):
+            with open(self.time_file_path, 'r') as time_file:
+                self.total_sampling_time = float(time_file.readline())
+        else:
+            self.total_sampling_time = 0
+
+    def _calculate_and_save_sampling_time(self):
+        current_time = time.time()
+        new_sampling_time = current_time - self.start_time
+        self.total_sampling_time += new_sampling_time
+        with open(self.time_file_path, 'w') as time_file:
+            time_file.write(str(self.total_sampling_time))
+
     def _clean_up_run_directory(self):
         if self.use_temporary_directory:
             self._move_temporary_directory_to_proper_path()
diff --git a/bilby/core/utils.py b/bilby/core/utils.py
index 6797fe821a96081db920daba9697c5daebbe83ce..d4704ae5f92e3cfdd34d0adc45501d437260ae5b 100644
--- a/bilby/core/utils.py
+++ b/bilby/core/utils.py
@@ -1236,6 +1236,13 @@ def kish_log_effective_sample_size(ln_weights):
     return log_n_eff
 
 
+def get_function_path(func):
+    if hasattr(func, "__module__") and hasattr(func, "__name__"):
+        return "{}.{}".format(func.__module__, func.__name__)
+    else:
+        return func
+
+
 class IllegalDurationAndSamplingFrequencyException(Exception):
     pass
 
diff --git a/bilby/gw/likelihood.py b/bilby/gw/likelihood.py
index 25d0c37ee3883d364f82c6fc7016ecedfd95cd8a..f32917775fa05c415dd8368ff54fcabc1fd94bce 100644
--- a/bilby/gw/likelihood.py
+++ b/bilby/gw/likelihood.py
@@ -196,7 +196,7 @@ class GravitationalWaveTransient(Likelihood):
                     "The waveform_generator {} is None. Setting from the "
                     "provided interferometers.".format(attr))
             elif wfg_attr != ifo_attr:
-                logger.warning(
+                logger.debug(
                     "The waveform_generator {} is not equal to that of the "
                     "provided interferometers. Overwriting the "
                     "waveform_generator.".format(attr))
diff --git a/bilby/gw/waveform_generator.py b/bilby/gw/waveform_generator.py
index ace0703537afbe525e9abaee9fbd3cb997b7b0ce..89432314bfddaa588329c9ebf9384b07ad5bae95 100644
--- a/bilby/gw/waveform_generator.py
+++ b/bilby/gw/waveform_generator.py
@@ -3,6 +3,7 @@ import numpy as np
 from ..core import utils
 from ..core.series import CoupledTimeAndFrequencySeries
 from .utils import PropertyAccessor
+from .conversion import convert_to_lal_binary_black_hole_parameters
 
 
 class WaveformGenerator(object):
@@ -57,7 +58,7 @@ class WaveformGenerator(object):
         self.time_domain_source_model = time_domain_source_model
         self.source_parameter_keys = self.__parameters_from_source_model()
         if parameter_conversion is None:
-            self.parameter_conversion = _default_parameter_conversion
+            self.parameter_conversion = convert_to_lal_binary_black_hole_parameters
         else:
             self.parameter_conversion = parameter_conversion
         if waveform_arguments is not None:
@@ -67,6 +68,15 @@ class WaveformGenerator(object):
         if isinstance(parameters, dict):
             self.parameters = parameters
         self._cache = dict(parameters=None, waveform=None, model=None)
+        utils.logger.info(
+            "Waveform generator initiated with\n"
+            "  frequency_domain_source_model: {}\n"
+            "  frequency_domain_source_model: {}\n"
+            "  parameter_conversion: {}"
+            .format(utils.get_function_path(self.frequency_domain_source_model),
+                    utils.get_function_path(self.time_domain_source_model),
+                    utils.get_function_path(self.parameter_conversion))
+        )
 
     def __repr__(self):
         if self.frequency_domain_source_model is not None:
@@ -77,7 +87,7 @@ class WaveformGenerator(object):
             tdsm_name = self.time_domain_source_model.__name__
         else:
             tdsm_name = None
-        if self.parameter_conversion.__name__ == '_default_parameter_conversion':
+        if self.parameter_conversion is None:
             param_conv_name = None
         else:
             param_conv_name = self.parameter_conversion.__name__
@@ -237,7 +247,3 @@ class WaveformGenerator(object):
             raise AttributeError('Either time or frequency domain source '
                                  'model must be provided.')
         return set(utils.infer_parameters_from_function(model))
-
-
-def _default_parameter_conversion(parmeters):
-    return parmeters, list()
diff --git a/cli_bilby/bilby_result.py b/cli_bilby/bilby_result.py
index d86a8e98dda4227c644265863bc1b80139dd37bd..6cacfb62db2cafa8ff5ed6797d690c5562875464 100644
--- a/cli_bilby/bilby_result.py
+++ b/cli_bilby/bilby_result.py
@@ -41,6 +41,10 @@ def setup_command_line_args():
                         help="Convert all results.", default=False)
     parser.add_argument("-m", "--merge", action='store_true',
                         help="Merge the set of runs, output saved using the outdir and label")
+    parser.add_argument("-e", "--extension", type=str, choices=["json", "hdf5"],
+                        default=True, help="Use given extension for the merged output file.")
+    parser.add_argument("-g", "--gzip", action="store_true",
+                        help="Gzip the merged output results file if using JSON format.")
     parser.add_argument("-o", "--outdir", type=str, default=None,
                         help="Output directory.")
     parser.add_argument("-l", "--label", type=str, default=None,
@@ -131,4 +135,6 @@ def main():
             result.label = args.label
         if args.outdir is not None:
             result.outdir = args.outdir
-        result.save_to_file()
+
+        extension = args.extension
+        result.save_to_file(gzip=args.gzip, extension=extension)
diff --git a/examples/gw_examples/injection_examples/fast_tutorial.py b/examples/gw_examples/injection_examples/fast_tutorial.py
index 6bfd0a0ed8bab100ee78d0fd03476a40b83b04fb..89119eb59163292257bec63dce20e71686f4dd41 100644
--- a/examples/gw_examples/injection_examples/fast_tutorial.py
+++ b/examples/gw_examples/injection_examples/fast_tutorial.py
@@ -42,6 +42,7 @@ waveform_arguments = dict(waveform_approximant='IMRPhenomPv2',
 waveform_generator = bilby.gw.WaveformGenerator(
     duration=duration, sampling_frequency=sampling_frequency,
     frequency_domain_source_model=bilby.gw.source.lal_binary_black_hole,
+    parameter_conversion=bilby.gw.conversion.convert_to_lal_binary_black_hole_parameters,
     waveform_arguments=waveform_arguments)
 
 # Set up interferometers.  In this case we'll use two interferometers
diff --git a/setup.py b/setup.py
index 97ee428ae0c8eaefb77d6a0a1443c49e04d66b71..d79d44655893308ce4612f2d7591bae58fd33291 100644
--- a/setup.py
+++ b/setup.py
@@ -39,7 +39,7 @@ def write_version_file(version):
     except Exception as e:
         print("Unable to obtain git version information, exception: {}"
               .format(e))
-        git_status = ''
+        git_status = 'release'
 
     version_file = '.version'
     if os.path.isfile(version_file) is False:
diff --git a/test/sampler_test.py b/test/sampler_test.py
index 0140b4f7b8a5c5d6d736adc1350e30ae25cf8f41..d9879543cfe8ab5c1413eb85d85b6ef806621f64 100644
--- a/test/sampler_test.py
+++ b/test/sampler_test.py
@@ -767,7 +767,8 @@ class TestPymultinest(unittest.TestCase):
                         n_iter_before_update=100, null_log_evidence=-1e90,
                         max_modes=100, mode_tolerance=-1e90, seed=-1,
                         context=0, write_output=True, log_zero=-1e100,
-                        max_iter=0, init_MPI=False, dump_callback=None)
+                        max_iter=0, init_MPI=False, dump_callback='dumper')
+        self.sampler.kwargs['dump_callback'] = 'dumper'  # Check like the dynesty print_func
         self.assertListEqual([1, 0], self.sampler.kwargs['wrapped_params'])  # Check this separately
         self.sampler.kwargs['wrapped_params'] = None  # The dict comparison can't handle lists
         self.assertDictEqual(expected, self.sampler.kwargs)
@@ -782,7 +783,7 @@ class TestPymultinest(unittest.TestCase):
                         n_iter_before_update=100, null_log_evidence=-1e90,
                         max_modes=100, mode_tolerance=-1e90, seed=-1,
                         context=0, write_output=True, log_zero=-1e100,
-                        max_iter=0, init_MPI=False, dump_callback=None)
+                        max_iter=0, init_MPI=False, dump_callback='dumper')
 
         for equiv in bilby.core.sampler.base_sampler.NestedSampler.npoints_equiv_kwargs:
             new_kwargs = self.sampler.kwargs.copy()
@@ -790,6 +791,7 @@ class TestPymultinest(unittest.TestCase):
             new_kwargs[
                 "wrapped_params"
             ] = None  # The dict comparison can't handle lists
+            new_kwargs['dump_callback'] = 'dumper'  # Check this like Dynesty print_func
             new_kwargs[equiv] = 123
             self.sampler.kwargs = new_kwargs
             self.assertDictEqual(expected, self.sampler.kwargs)
diff --git a/test/waveform_generator_test.py b/test/waveform_generator_test.py
index 69e3112c07ea995492689fdca5ee40c83a64a0f1..d759c2f9367f7644cdf457b27050aba4a671747f 100644
--- a/test/waveform_generator_test.py
+++ b/test/waveform_generator_test.py
@@ -73,7 +73,7 @@ class TestWaveformGeneratorInstantiationWithoutOptionalParameters(unittest.TestC
                 self.waveform_generator.start_time,
                 self.waveform_generator.frequency_domain_source_model.__name__,
                 self.waveform_generator.time_domain_source_model,
-                None,
+                bilby.gw.conversion.convert_to_lal_binary_black_hole_parameters.__name__,
                 self.waveform_generator.waveform_arguments,
             )
         )
@@ -92,7 +92,7 @@ class TestWaveformGeneratorInstantiationWithoutOptionalParameters(unittest.TestC
                 self.waveform_generator.start_time,
                 self.waveform_generator.frequency_domain_source_model,
                 self.waveform_generator.time_domain_source_model.__name__,
-                None,
+                bilby.gw.conversion.convert_to_lal_binary_black_hole_parameters.__name__,
                 self.waveform_generator.waveform_arguments,
             )
         )