예제 #1
0
def plot_two_level_threshold(results, fig=100, plot_initial_estimate=False):
    plt.figure(fig)
    plt.clf()
    bin_centres = results['histogram']['bin_centres']
    counts = results['histogram']['counts']
    plt.bar(bin_centres,
            counts,
            width=bin_centres[1] - bin_centres[0],
            label='histogram')
    plt.ylabel('Counts')
    plt.xlabel('Signal [a.u.]')
    plot_vertical_line(results['signal_threshold'], label='threshold')
    plot_double_gaussian_fit(results['double_gaussian_fit'], bin_centres)
    plt.title('Result of two level threshold processing')

    if plot_initial_estimate:
        xdata = np.linspace(bin_centres[0], bin_centres[-1], 300)
        initial_estimate = results['double_gaussian_fit'][
            'parameters initial guess']
        left0 = initial_estimate[::2][::-1]
        right0 = initial_estimate[1::2][::-1]
        plt.plot(xdata,
                 gaussian(xdata, *left0),
                 ':g',
                 label='initial estimate left')
        plt.plot(xdata,
                 gaussian(xdata, *right0),
                 ':r',
                 label='initial estimate right')
 def test_gaussian(self):
     y = gaussian(np.array([0.0, 1., 2.]), 1.0, .2)
     self.assertIsInstance(y, np.ndarray)
     np.testing.assert_almost_equal(
         y,
         np.array([3.72665317e-06, 1.00000000e+00, 3.72665317e-06]),
         decimal=6)
예제 #3
0
 def test_fit_gaussian_no_offset(self):
     x_data = np.linspace(0, 10, 100)
     gauss_data = gaussian(x_data, mean=4, std=1, amplitude=5)
     noise = np.random.rand(100) - .5
     parameters, result_dict = fit_gaussian(x_data=x_data, y_data=(gauss_data + noise), estimate_offset=0)
     np.testing.assert_array_almost_equal(result_dict['fitted_parameters'], np.array([4, 1, 5.]), decimal=1)
     np.testing.assert_array_almost_equal(parameters, result_dict['fitted_parameters'])
     self.assertTrue(result_dict['reduced_chi_squared'] < .2)
예제 #4
0
 def test_fit_gaussian(self):
     x_data = np.linspace(0, 10, 100)
     gauss_data = 0.1 + gaussian(x_data, mean=4, std=1, amplitude=5)
     noise = np.random.rand(100) - .5
     [mean, s, amplitude, offset], _ = fit_gaussian(x_data=x_data, y_data=(gauss_data + noise))
     self.assertTrue(3.5 < mean < 4.5)
     self.assertTrue(0.5 < s < 1.5)
     self.assertTrue(4.5 < amplitude < 5.5)
     self.assertAlmostEqual(offset, 0.1, places=0)
예제 #5
0
def _plot_rts_histogram(data, num_bins, double_gaussian_fit, split,
                        figure_title):
    _, bins, _ = plt.hist(data, bins=num_bins)
    bincentres = np.array([(bins[i] + bins[i + 1]) / 2
                           for i in range(0,
                                          len(bins) - 1)])

    get_left_mean_std_amplitude = operator.itemgetter(4, 2, 0)
    get_right_mean_std_amplitude = operator.itemgetter(5, 3, 1)
    left_gaussian = list(get_left_mean_std_amplitude(double_gaussian_fit))
    right_gaussian = list(get_right_mean_std_amplitude(double_gaussian_fit))

    plt.plot(bincentres,
             double_gaussian(bincentres, double_gaussian_fit),
             '-m',
             label='Fitted double gaussian')
    plt.plot(bincentres,
             gaussian(bincentres, *left_gaussian),
             'g',
             label='Left Gaussian',
             alpha=.85,
             linewidth=.75)
    plt.plot(bincentres,
             gaussian(bincentres, *right_gaussian),
             'r',
             label='Right Gaussian',
             alpha=.85,
             linewidth=.75)
    plt.plot(split,
             double_gaussian(split, double_gaussian_fit),
             'ro',
             markersize=8,
             label='split: %.3f' % split)
    plt.xlabel('Measured value (a.u.)')
    plt.ylabel('Data points per bin')
    plt.legend()
    plt.title(figure_title)
예제 #6
0
def plot_two_level_threshold(results: dict,
                             fig: int = 100,
                             plot_initial_estimate: bool = False):
    separation = results['separation']
    threshold = results['signal_threshold']

    ax = get_axis(fig)
    bin_centres = results['histogram']['bin_centres']
    counts = results['histogram']['counts']
    ax.bar(bin_centres,
           counts,
           width=bin_centres[1] - bin_centres[0],
           label='histogram')
    ax.set_ylabel('Counts')
    ax.set_xlabel('Signal [a.u.]')
    plot_vertical_line(threshold, label='threshold')
    plot_double_gaussian_fit(results['double_gaussian_fit'], bin_centres)

    ax.set_title(
        f'Two-level signal: separation {separation:.3f}, threshold {threshold:.3g}'
    )

    if plot_initial_estimate:
        xdata = np.linspace(bin_centres[0], bin_centres[-1], 300)
        initial_estimate = results['double_gaussian_fit'][
            'parameters initial guess']
        left0 = initial_estimate[::2][::-1]
        right0 = initial_estimate[1::2][::-1]
        ax.plot(xdata,
                gaussian(xdata, *left0),
                ':g',
                label='initial estimate left')
        ax.plot(xdata,
                gaussian(xdata, *right0),
                ':r',
                label='initial estimate right')
예제 #7
0
def refit_double_gaussian(result_dict,
                          x_data,
                          y_data,
                          gaussian_amplitude_ratio_threshold=8):
    """ Improve fit of double Gaussian by estimating the initial parameters based on an existing fit

    Args:
        result_dict(dict): Result dictionary from fit_double_gaussian
        x_data (array): Independent data
        y_data (array): Signal data
        gaussian_amplitude_ratio_threshold (float): If ratio between amplitudes of Gaussian peaks is larger than
                            this fit, re-estimate
    Returns:
        Dictionary with improved fitting results
    """

    mean = operator.itemgetter(0)
    std = operator.itemgetter(1)
    amplitude = operator.itemgetter(2)

    if amplitude(result_dict['left']) > amplitude(result_dict['right']):
        large_gaussian_parameters = result_dict['left']
        small_gaussian_parameters = result_dict['right']
    else:
        large_gaussian_parameters = result_dict['right']
        small_gaussian_parameters = result_dict['left']
    gaussian_ratio = amplitude(large_gaussian_parameters) / amplitude(
        small_gaussian_parameters)

    if gaussian_ratio > gaussian_amplitude_ratio_threshold:
        # re-estimate by fitting a single gaussian to the data remaining after removing the main gaussian
        y_residual = y_data - gaussian(x_data, *large_gaussian_parameters)
        idx = np.logical_and(
            x_data > mean(large_gaussian_parameters) -
            1.5 * std(large_gaussian_parameters),
            x_data < mean(large_gaussian_parameters) +
            1.5 * std(large_gaussian_parameters))
        y_residual[idx] = 0
        gauss_fit, _ = fit_gaussian(x_data, y_residual)

        initial_parameters = _double_gaussian_parameters(
            large_gaussian_parameters, gauss_fit[:3])
        _, result_dict_refit = fit_double_gaussian(
            x_data, y_data, initial_params=initial_parameters)
        if result_dict_refit['reduced_chi_squared'] < result_dict[
                'reduced_chi_squared']:
            result_dict = result_dict_refit
    return result_dict
예제 #8
0
 def gaussian_model(x, mean, sigma, amplitude):  # type: ignore
     """ Gaussian helper function for lmfit """
     y = gaussian(x, mean, sigma, amplitude)
     return y
예제 #9
0
 def gaussian_model(x, mean, sigma, amplitude, offset):
     """ Gaussian helper function for lmfit """
     y = gaussian(x, mean, sigma, amplitude, offset)
     return y
예제 #10
0
 def _double_gaussian(x, A_dn, A_up, sigma_dn, sigma_up, mean_dn, mean_up):
     """ Double Gaussian helper function for lmfit """
     gauss_dn = gaussian(x, mean_dn, sigma_dn, A_dn)
     gauss_up = gaussian(x, mean_up, sigma_up, A_up)
     double_gauss = gauss_dn + gauss_up
     return double_gauss
예제 #11
0
 def setUp(self):
     x_data = np.arange(0, 100)
     y_data = np.random.rand(x_data.size)
     y_data += gaussian(x_data, 30, 6, 30)
     y_data += gaussian(x_data, 70, 8, 70)
     self.example_data = (x_data, y_data)