diff --git a/bilby/gw/conversion.py b/bilby/gw/conversion.py
index e4ffcff231c50724dae7bcb849851d96aef6ac65..ec39959c956b10e28a7a2ec3fb76e0cf35848ab8 100644
--- a/bilby/gw/conversion.py
+++ b/bilby/gw/conversion.py
@@ -954,23 +954,23 @@ def compute_snrs(sample, likelihood):
                     ifo.matched_filter_snr(signal=signal)
                 sample['{}_optimal_snr'.format(ifo.name)] = \
                     ifo.optimal_snr_squared(signal=signal) ** 0.5
+
         else:
             logger.info(
                 'Computing SNRs for every sample, this may take some time.')
-            all_interferometers = likelihood.interferometers
-            matched_filter_snrs = {ifo.name: [] for ifo in all_interferometers}
-            optimal_snrs = {ifo.name: [] for ifo in all_interferometers}
+
+            matched_filter_snrs = {ifo.name: [] for ifo in likelihood.interferometers}
+            optimal_snrs = {ifo.name: [] for ifo in likelihood.interferometers}
+
             for ii in range(len(sample)):
                 signal_polarizations =\
                     likelihood.waveform_generator.frequency_domain_strain(
                         dict(sample.iloc[ii]))
-                for ifo in all_interferometers:
-                    signal = ifo.get_detector_response(
-                        signal_polarizations, sample.iloc[ii])
-                    matched_filter_snrs[ifo.name].append(
-                        ifo.matched_filter_snr(signal=signal))
-                    optimal_snrs[ifo.name].append(
-                        ifo.optimal_snr_squared(signal=signal) ** 0.5)
+                likelihood.parameters.update(sample.iloc[ii])
+                for ifo in likelihood.interferometers:
+                    per_detector_snr = likelihood.calculate_snrs(signal_polarizations, ifo)
+                    matched_filter_snrs[ifo.name].append(per_detector_snr.complex_matched_filter_snr.real)
+                    optimal_snrs[ifo.name].append(per_detector_snr.optimal_snr_squared ** 0.5)
 
             for ifo in likelihood.interferometers:
                 sample['{}_matched_filter_snr'.format(ifo.name)] =\
@@ -978,8 +978,6 @@ def compute_snrs(sample, likelihood):
                 sample['{}_optimal_snr'.format(ifo.name)] =\
                     optimal_snrs[ifo.name]
 
-            likelihood.interferometers = all_interferometers
-
     else:
         logger.debug('Not computing SNRs.')
 
diff --git a/bilby/gw/likelihood.py b/bilby/gw/likelihood.py
index e3ff0733879bfe57ee863ca2e3a6750e67e323cb..1ee33f0545438fea7596a19bbadf3ff1dab8e506 100644
--- a/bilby/gw/likelihood.py
+++ b/bilby/gw/likelihood.py
@@ -21,6 +21,7 @@ from .prior import BBHPriorDict
 from .source import lal_binary_black_hole
 from .utils import noise_weighted_inner_product, build_roq_weights, blockwise_dot_product
 from .waveform_generator import WaveformGenerator
+from collections import namedtuple
 
 
 class GravitationalWaveTransient(likelihood.Likelihood):
@@ -124,6 +125,40 @@ class GravitationalWaveTransient(likelihood.Likelihood):
                     "waveform_generator.".format(attr))
             setattr(self.waveform_generator, attr, ifo_attr)
 
+    def calculate_snrs(self, waveform_polarizations, interferometer):
+        """
+        Compute the snrs
+
+        Parameters
+        ----------
+        waveform_polarizations: dict
+            A dictionary of waveform polarizations and the corresponding array
+        interferometer: bilby.gw.detector.Interferometer
+            The bilby interferometer object
+
+        """
+        signal = interferometer.get_detector_response(
+            waveform_polarizations, self.parameters)
+        d_inner_h = interferometer.inner_product(signal=signal)
+        optimal_snr_squared = interferometer.optimal_snr_squared(signal=signal)
+        complex_matched_filter_snr = d_inner_h / (optimal_snr_squared**0.5)
+        CalculatedSNRs = namedtuple(
+            'CalculatedSNRs', ['d_inner_h', 'optimal_snr_squared', 'complex_matched_filter_snr', 'd_inner_h_squared_tc_array'])
+
+        if self.time_marginalization:
+            d_inner_h_squared_tc_array =\
+                4 / self.waveform_generator.duration * np.fft.fft(
+                    signal[0:-1] *
+                    interferometer.frequency_domain_strain.conjugate()[0:-1] /
+                    interferometer.power_spectral_density_array[0:-1])
+        else:
+            d_inner_h_squared_tc_array = None
+
+        return CalculatedSNRs(
+            d_inner_h=d_inner_h, optimal_snr_squared=optimal_snr_squared,
+            complex_matched_filter_snr=complex_matched_filter_snr,
+            d_inner_h_squared_tc_array=d_inner_h_squared_tc_array)
+
     def _check_prior_is_set(self, key):
         if key not in self.priors or not isinstance(
                 self.priors[key], Prior):
@@ -167,23 +202,23 @@ class GravitationalWaveTransient(likelihood.Likelihood):
         if waveform_polarizations is None:
             return np.nan_to_num(-np.inf)
 
-        d_inner_h = 0
-        optimal_snr_squared = 0
+        d_inner_h = 0.
+        optimal_snr_squared = 0.
+        complex_matched_filter_snr = 0.
         d_inner_h_squared_tc_array = np.zeros(
             self.interferometers.frequency_array[0:-1].shape,
             dtype=np.complex128)
+
         for interferometer in self.interferometers:
-            signal_ifo = interferometer.get_detector_response(
-                waveform_polarizations, self.parameters)
+            per_detector_snr = self.calculate_snrs(
+                waveform_polarizations, interferometer)
+
+            d_inner_h += per_detector_snr.d_inner_h
+            optimal_snr_squared += per_detector_snr.optimal_snr_squared
+            complex_matched_filter_snr += per_detector_snr.complex_matched_filter_snr
 
-            d_inner_h += interferometer.inner_product(signal=signal_ifo)
-            optimal_snr_squared += interferometer.optimal_snr_squared(signal=signal_ifo)
             if self.time_marginalization:
-                d_inner_h_squared_tc_array +=\
-                    4 / self.waveform_generator.duration * np.fft.fft(
-                        signal_ifo[0:-1] *
-                        interferometer.frequency_domain_strain.conjugate()[0:-1] /
-                        interferometer.power_spectral_density_array[0:-1])
+                d_inner_h_squared_tc_array += per_detector_snr.d_inner_h_squared_tc_array
 
         if self.time_marginalization:
 
@@ -448,63 +483,65 @@ class ROQGravitationalWaveTransient(GravitationalWaveTransient):
         self.frequency_nodes_linear =\
             waveform_generator.waveform_arguments['frequency_nodes_linear']
 
-    def log_likelihood_ratio(self):
-        optimal_snr_squared = 0.
-        d_inner_h = 0.
-
-        waveform = self.waveform_generator.frequency_domain_strain(
-            self.parameters)
-        if waveform is None:
-            return np.nan_to_num(-np.inf)
+    def calculate_snrs(self, signal, interferometer):
+        """
+        Compute the snrs for ROQ
 
-        for ifo in self.interferometers:
+        Parameters
+        ----------
+        signal: waveform
 
-            f_plus = ifo.antenna_response(
-                self.parameters['ra'], self.parameters['dec'],
-                self.parameters['geocent_time'], self.parameters['psi'], 'plus')
-            f_cross = ifo.antenna_response(
-                self.parameters['ra'], self.parameters['dec'],
-                self.parameters['geocent_time'], self.parameters['psi'], 'cross')
-
-            dt = ifo.time_delay_from_geocenter(
-                self.parameters['ra'], self.parameters['dec'],
-                ifo.strain_data.start_time)
-            ifo_time = self.parameters['geocent_time'] + dt - \
-                ifo.strain_data.start_time
-
-            h_plus_linear = f_plus * waveform['linear']['plus']
-            h_cross_linear = f_cross * waveform['linear']['cross']
-            h_plus_quadratic = f_plus * waveform['quadratic']['plus']
-            h_cross_quadratic = f_cross * waveform['quadratic']['cross']
-
-            indices, in_bounds = self._closest_time_indices(
-                ifo_time, self.time_samples)
-            if not in_bounds:
-                return np.nan_to_num(-np.inf)
-
-            d_inner_h_tc_array = np.einsum(
-                'i,ji->j', np.conjugate(h_plus_linear + h_cross_linear),
-                self.weights[ifo.name + '_linear'][indices])
-
-            d_inner_h += interp1d(
-                self.time_samples[indices],
-                d_inner_h_tc_array, kind='cubic')(ifo_time)
-
-            optimal_snr_squared += \
-                np.vdot(np.abs(h_plus_quadratic + h_cross_quadratic)**2,
-                        self.weights[ifo.name + '_quadratic'])
+        interferometer: interferometer object
 
-        if self.distance_marginalization:
-            rho_mf_ref, rho_opt_ref = self._setup_rho(d_inner_h, optimal_snr_squared)
-            if self.phase_marginalization:
-                rho_mf_ref = abs(rho_mf_ref)
-            log_l = self._interp_dist_margd_loglikelihood(rho_mf_ref.real, rho_opt_ref)[0]
-        else:
-            if self.phase_marginalization:
-                d_inner_h = self._bessel_function_interped(abs(d_inner_h))
-            log_l = d_inner_h - optimal_snr_squared / 2
+        """
 
-        return log_l.real
+        f_plus = interferometer.antenna_response(
+            self.parameters['ra'], self.parameters['dec'],
+            self.parameters['geocent_time'], self.parameters['psi'], 'plus')
+        f_cross = interferometer.antenna_response(
+            self.parameters['ra'], self.parameters['dec'],
+            self.parameters['geocent_time'], self.parameters['psi'], 'cross')
+
+        dt = interferometer.time_delay_from_geocenter(
+            self.parameters['ra'], self.parameters['dec'],
+            interferometer.strain_data.start_time)
+        ifo_time = self.parameters['geocent_time'] + dt - \
+            interferometer.strain_data.start_time
+
+        h_plus_linear = f_plus * signal['linear']['plus']
+        h_cross_linear = f_cross * signal['linear']['cross']
+        h_plus_quadratic = f_plus * signal['quadratic']['plus']
+        h_cross_quadratic = f_cross * signal['quadratic']['cross']
+
+        CalculatedSNRs = namedtuple(
+            'CalculatedSNRs', ['d_inner_h', 'optimal_snr_squared', 'complex_matched_filter_snr', 'd_inner_h_squared_tc_array'])
+
+        indices, in_bounds = self._closest_time_indices(ifo_time, self.time_samples)
+        if not in_bounds:
+            return CalculatedSNRs(
+                d_inner_h=np.nan_to_num(-np.inf), optimal_snr_squared=0,
+                complex_matched_filter_snr=np.nan_to_num(-np.inf),
+                d_inner_h_squared_tc_array=None)
+
+        d_inner_h_tc_array = np.einsum(
+            'i,ji->j', np.conjugate(h_plus_linear + h_cross_linear),
+            self.weights[interferometer.name + '_linear'][indices])
+
+        d_inner_h = interp1d(
+            self.time_samples[indices],
+            d_inner_h_tc_array, kind='cubic')(ifo_time)
+
+        optimal_snr_squared = \
+            np.vdot(np.abs(h_plus_quadratic + h_cross_quadratic)**2,
+                    self.weights[interferometer.name + '_quadratic'])
+
+        complex_matched_filter_snr = d_inner_h / (optimal_snr_squared**0.5)
+        d_inner_h_squared_tc_array = None
+
+        return CalculatedSNRs(
+            d_inner_h=d_inner_h, optimal_snr_squared=optimal_snr_squared,
+            complex_matched_filter_snr=complex_matched_filter_snr,
+            d_inner_h_squared_tc_array=d_inner_h_squared_tc_array)
 
     @staticmethod
     def _closest_time_indices(time, samples):