Exemple #1
0
    def test_broadening_normalisation(self):
        """Check broadening implementations do not change overall intensity"""
        np.random.seed(0)

        # Use a strange bin width to catch bin-width-dependent behaviour
        bins = np.linspace(0, 5000, 2000)

        def sigma_func(frequencies):
            return 2 + frequencies * 1e-2

        n_peaks = 10
        frequencies = np.random.random(n_peaks) * 4000
        sigma = sigma_func(frequencies)
        s_dft = np.random.random(n_peaks) * 10

        pre_broadening_total = sum(s_dft)

        # Full Gaussian should reproduce null total
        for scheme in ('none', 'gaussian'):
            freq_points, spectrum = broadening.broaden_spectrum(frequencies,
                                                                bins,
                                                                s_dft,
                                                                sigma,
                                                                scheme=scheme)
            self.assertAlmostEqual(
                sum(spectrum),
                pre_broadening_total,
            )

        # Normal scheme reproduces area as well as total;
        freq_points, full_spectrum = broadening.broaden_spectrum(
            frequencies, bins, s_dft, sigma, scheme='normal')
        self.assertAlmostEqual(
            np.trapz(spectrum, x=freq_points),
            pre_broadening_total * (bins[1] - bins[0]),
        )
        self.assertAlmostEqual(sum(spectrum), pre_broadening_total)

        # truncated forms will be a little off but shouldn't be _too_ off
        for scheme in ('gaussian_truncated', 'normal_truncated'):

            freq_points, trunc_spectrum = broadening.broaden_spectrum(
                frequencies, bins, s_dft, sigma, scheme)
            self.assertLess(
                abs(sum(full_spectrum) - sum(trunc_spectrum)) /
                sum(full_spectrum), 0.03)

        # Interpolated methods need histogram input and smooth sigma
        hist_spec, _ = np.histogram(frequencies, bins, weights=s_dft)
        hist_sigma = sigma_func(freq_points)
        freq_points, interp_spectrum = broadening.broaden_spectrum(
            freq_points, bins, hist_spec, hist_sigma, scheme='interpolate')
        self.assertLess(
            abs(sum(interp_spectrum) - pre_broadening_total) /
            pre_broadening_total, 0.05)
    def test_out_of_bounds(self):
        """Check schemes allowing arbitrary placement can handle data beyond bins"""
        frequencies = np.array([2000.])
        bins = np.linspace(0, 100, 100)
        s_dft = np.array([1.])
        sigma = np.array([3.])

        schemes = ['none',
                   'gaussian', 'gaussian_truncated',
                   'normal', 'normal_truncated']

        for scheme in schemes:
            broadening.broaden_spectrum(frequencies, bins, s_dft, sigma, scheme=scheme)
    def test_broaden_spectrum_values(self):
        """Check broadening implementations give similar values"""

        # Use dense bins with a single peak for fair comparison
        npts = 1000
        bins = np.linspace(0, 100, npts + 1)
        freq_points = (bins[1:] + bins[:-1]) / 2
        sigma = freq_points * 0.1 + 1
        s_dft = np.zeros(npts)
        s_dft[npts // 2] = 2

        schemes = ['gaussian', 'gaussian_truncated',
                   'normal', 'normal_truncated',
                   'interpolate']

        results = {}
        for scheme in schemes:
            _, results[scheme] = broadening.broaden_spectrum(
                freq_points, bins, s_dft, sigma, scheme)

        for scheme in schemes:
            # Interpolate scheme is approximate so just check a couple of sig.fig.
            if scheme == 'interpolate':
                places = 3
            else:
                places = 6
            self.assertAlmostEqual(results[scheme][(npts // 2) + 20],
                                   0.01257,
                                   places=places)