コード例 #1
0
ファイル: fitting_test.py プロジェクト: lbl-anp/becquerel
def test_gauss_gauss_gauss_line(method):
    model = (bq.fitting.GaussModel(prefix="gauss0_") +
             bq.fitting.GaussModel(prefix="gauss1_") +
             bq.fitting.GaussModel(prefix="gauss2_") +
             bq.fitting.LineModel(prefix="line_"))
    params = {
        "gauss0_amp": 1e5,
        "gauss0_mu": 80.0,
        "gauss0_sigma": 5.0,
        "gauss1_amp": 1e5,
        "gauss1_mu": 100.0,
        "gauss1_sigma": 5.0,
        "gauss2_amp": 1e5,
        "gauss2_mu": 120.0,
        "gauss2_sigma": 5.0,
        "line_m": -10.0,
        "line_b": 1e4,
    }
    data = sim_data(y_func=model.eval, x_min=0, x_max=200, **params)

    fitter = bq.Fitter(model, **data)
    for i in range(3):
        n = f"gauss{i}_mu"
        fitter.params[n].set(value=params[n])
    fitter.fit(method)
    compare_params(
        true_params=params,
        fit_params=fitter.best_values,
        rtol=0.05,
        fitter=fitter,
    )
コード例 #2
0
ファイル: fitting_test.py プロジェクト: lbl-anp/becquerel
    def test_with_init(self, sim_high_stat):
        fitter = bq.Fitter(
            sim_high_stat["model"],
            x=sim_high_stat["data"]["x"],
            y=sim_high_stat["data"]["y"],
            dx=sim_high_stat["data"]["dx"],
            y_unc=sim_high_stat["data"]["y_unc"],
            roi=sim_high_stat["roi"],
        )
        fitter.fit(sim_high_stat["method"])
        compare_params(
            true_params=sim_high_stat["params"],
            fit_params=fitter.best_values,
            rtol=sim_high_stat["rtol"],
            fitter=fitter,
        )
        if sim_high_stat["method"] in ["lmfit-pml", "minuit-pml"]:
            compare_counts(fitter)
        # fitter.custom_plot()
        # plt.show()

        # Test some other properties while we're at it
        assert isinstance(str(fitter), str)
        assert fitter.name is None or isinstance(fitter.name, str)
        assert fitter.xmode is None or isinstance(fitter.xmode, str)
        assert fitter.ymode is None or isinstance(fitter.ymode, str)
        assert isinstance(fitter.param_names, list)
        assert len(fitter.param_names) > 0
        assert len(fitter.init_values) > 0
        assert len(fitter.best_values) > 0
        assert fitter.success
        assert bq.fitting._is_count_like(fitter.y_roi)
        assert not bq.fitting._is_count_like(fitter.y_roi * 0.5)
コード例 #3
0
 def test_no_roi(self, sim_high_stat):
     fitter = bq.Fitter(sim_high_stat['model'])
     fitter.set_data(**sim_high_stat['data'])
     fitter.fit(sim_high_stat['method'])
     compare_params(true_params=sim_high_stat['params'],
                    fit_params=fitter.result.best_values,
                    rtol=sim_high_stat['rtol'], fitter=fitter)
     if sim_high_stat['method'] == 'lmfit-pml':
         compare_counts(fitter)
コード例 #4
0
ファイル: fitting_test.py プロジェクト: lbl-anp/becquerel
def sim_high_stat(request):
    """Synthetic data with high count statistics"""
    out = deepcopy(request.param)
    out["fitter"] = bq.Fitter(out["model"])
    sim_data_kwargs = out["sim_data_kwargs"].copy()
    sim_data_kwargs.update(out["params"])
    out["data"] = sim_data(y_func=out["fitter"].eval,
                           binning=out["binning"],
                           **sim_data_kwargs)
    return out
コード例 #5
0
def sim_high_stat(request):
    """Fake data with high count statistics"""
    out = deepcopy(request.param)
    out['fitter'] = bq.Fitter(out['model'])
    sim_data_kwargs = out['sim_data_kwargs'].copy()
    sim_data_kwargs.update(out['params'])
    out['data'] = sim_data(y_func=out['fitter'].eval,
                           binning=out['binning'],
                           **sim_data_kwargs)
    return out
コード例 #6
0
ファイル: fitting_test.py プロジェクト: lbl-anp/becquerel
def test_method_err(sim_high_stat):
    """Test that unsupported fit methods raise appropriate errors."""
    if sim_high_stat["method"] == "bad-method":
        with pytest.raises(bq.FittingError):
            bq.Fitter(
                sim_high_stat["model"],
                x=sim_high_stat["data"]["x"],
                y=sim_high_stat["data"]["y"],
                dx=sim_high_stat["data"]["dx"],
                y_unc=sim_high_stat["data"]["y_unc"],
            )
    elif sim_high_stat["method"] == "minuit":
        with pytest.raises(NotImplementedError):
            bq.Fitter(
                sim_high_stat["model"],
                x=sim_high_stat["data"]["x"],
                y=sim_high_stat["data"]["y"],
                dx=sim_high_stat["data"]["dx"],
                y_unc=sim_high_stat["data"]["y_unc"],
            )
コード例 #7
0
ファイル: fitting_test.py プロジェクト: lbl-anp/becquerel
 def test_no_roi(self, sim_high_stat):
     fitter = bq.Fitter(sim_high_stat["model"])
     fitter.set_data(**sim_high_stat["data"])
     fitter.fit(sim_high_stat["method"])
     compare_params(
         true_params=sim_high_stat["params"],
         fit_params=fitter.best_values,
         rtol=sim_high_stat["rtol"],
         fitter=fitter,
     )
     if sim_high_stat["method"] in ["lmfit-pml", "minuit-pml"]:
         compare_counts(fitter)
コード例 #8
0
 def test_with_init(self, sim_high_stat):
     fitter = bq.Fitter(
         sim_high_stat['model'],
         x=sim_high_stat['data']['x'],
         y=sim_high_stat['data']['y'],
         dx=sim_high_stat['data']['dx'],
         y_unc=sim_high_stat['data']['y_unc'],
         roi=sim_high_stat['roi'])
     fitter.fit(sim_high_stat['method'])
     compare_params(true_params=sim_high_stat['params'],
                    fit_params=fitter.result.best_values,
                    rtol=sim_high_stat['rtol'], fitter=fitter)
     if sim_high_stat['method'] == 'lmfit-pml':
         compare_counts(fitter)
コード例 #9
0
ファイル: fitting_test.py プロジェクト: lbl-anp/becquerel
def test_lmfit_and_bq_models(method):
    models = {
        "bq": (bq.fitting.GaussModel(prefix="gauss0_") +
               bq.fitting.GaussModel(prefix="gauss1_") +
               bq.fitting.LineModel(prefix="line_")),
        "mixed": (bq.fitting.GaussModel(prefix="gauss0_") +
                  bq.fitting.GaussModel(prefix="gauss1_") +
                  lmfit.models.LinearModel(prefix="line_")),
    }
    peak_params = {
        "gauss0_amp": 1e5,
        "gauss0_mu": 80.0,
        "gauss0_sigma": 5.0,
        "gauss1_amp": 1e5,
        "gauss1_mu": 120.0,
        "gauss1_sigma": 5.0,
    }
    line_params = {
        "bq": {
            "line_m": -10.0,
            "line_b": 1e4
        },
        "mixed": {
            "line_slope": -10.0,
            "line_intercept": 1e4
        },
    }
    for k in models:
        params = {**peak_params, **line_params[k]}
        data = sim_data(
            y_func=models[k].eval,
            x_min=0,
            x_max=200,
            **params,
        )

        fitter = bq.Fitter(models[k], **data)
        for i in range(2):
            n = f"gauss{i}_mu"
            fitter.params[n].set(value=params[n])
        fitter.fit(method)
        compare_params(
            true_params=params,
            fit_params=fitter.best_values,
            rtol=0.05,
            fitter=fitter,
        )
コード例 #10
0
ファイル: fitting_test.py プロジェクト: lbl-anp/becquerel
def test_gauss_dbl_exp(method):
    params = {
        "amp": 1e5,
        "mu": 100.0,
        "sigma": 5.0,
        "ltail_ratio": 0.3,
        "ltail_slope": 0.07,
        "ltail_cutoff": 1.0,
        "rtail_ratio": 0.1,
        "rtail_slope": -0.03,
        "rtail_cutoff": 1.0,
    }
    model = bq.fitting.GaussDblExpModel()
    data = sim_data(y_func=model.eval, x_min=0, x_max=200, **params)

    fitter = bq.Fitter(model, **data)
    # "fix" params for lmfit
    fitter.params["ltail_cutoff"].min = 0.99
    fitter.params["ltail_cutoff"].value = 1.0
    fitter.params["ltail_cutoff"].max = 1.01
    fitter.params["rtail_cutoff"].min = 0.99
    fitter.params["rtail_cutoff"].value = 1.0
    fitter.params["rtail_cutoff"].max = 1.01

    # "fix" params for minuit
    limits = {
        "ltail_cutoff": (0.99, 1.01),
        "rtail_cutoff": (0.99, 1.01),
    }
    fitter.fit(method, guess=params, limits=limits)

    compare_params(
        true_params=params,
        fit_params=fitter.best_values,
        rtol=0.05,
        fitter=fitter,
    )
コード例 #11
0
ファイル: fitting_test.py プロジェクト: lbl-anp/becquerel
    def test_component_areas(self, sim_high_stat):
        fitter = bq.Fitter(sim_high_stat["model"])
        fitter.set_data(**sim_high_stat["data"])
        fitter.set_roi(*sim_high_stat["roi"])
        fitter.fit(sim_high_stat["method"])

        # Area calculations do not support non-linear bins!
        if sim_high_stat["binning"] != "linear":
            with pytest.raises(NotImplementedError):
                fitter.calc_area_and_unc()
            return

        # Sometimes the fit result does not have a reliable covariance matrix, but alas.
        # We can at least check that it properly warns, then skip the rest of the tests
        if fitter.covariance is None:
            with pytest.warns(bq.fitting.FittingWarning):
                a = fitter.calc_area_and_unc()
                assert a.std_dev == 0
            return

        # The covariance check above only runs a handful of times and is subject to the
        # fit quality, so let's synthetically create a zero covariance case and test it
        fitter_copy = deepcopy(fitter)
        fitter_copy.fit(sim_high_stat["method"])
        if fitter_copy.covariance is not None:
            if "minuit" in fitter_copy.backend:
                fitter_copy.result._covariance *= 0
            else:
                fitter_copy.result.covar *= 0
            with pytest.warns(bq.fitting.FittingWarning):
                a = fitter_copy.calc_area_and_unc()
                assert a.std_dev == 0

        # Area under the entire curve
        a0 = fitter.calc_area_and_unc()
        assert a0.nominal_value > 0
        assert a0.std_dev > 0
        assert a0.std_dev < a0.nominal_value

        # Area under the ROI
        a1 = fitter.calc_area_and_unc(x=fitter.x_roi)
        # Should be strictly smaller than the area under the entire curve, but we need
        # to allow for a bit of floating point weirdness.
        assert a1.nominal_value / a0.nominal_value < 1 + 1e-9

        # Component-wise areas
        for component in fitter.model.components:
            name = component.prefix.strip("_")
            a2 = fitter.calc_area_and_unc(component=component)
            a3 = fitter.calc_area_and_unc(component=name)
            assert np.isclose(a2.nominal_value, a3.nominal_value)
            assert np.isclose(a2.std_dev, a3.std_dev)
            a4 = fitter.calc_area_and_unc(component=component, x=fitter.x_roi)
            a5 = fitter.calc_area_and_unc(component=name, x=fitter.x_roi)
            assert np.isclose(a4.nominal_value, a5.nominal_value)
            assert np.isclose(a4.std_dev, a5.std_dev)

            if name == "gauss":
                # If the component is a Gaussian, the calculated area should be very
                # close to its given amplitude parameter.
                a_theor = HIGH_STAT_SIM_PARAMS["base_model_params"][name][
                    "amp"]
                assert np.isclose(a2.nominal_value, a_theor, rtol=0.01)

                # Additionally, if there's no background, the uncertainty should be very
                # close to the sqrt of the amplitude (at least with minuit!)
                if len(fitter.model.components
                       ) == 1 and "minuit" in fitter.backend:
                    assert np.isclose(a2.std_dev, np.sqrt(a_theor), rtol=0.01)
コード例 #12
0
"""Partionally functional fit line example:
    -Read in SPE file
    -Store in dataframe
    -Plot Spectrum
        This example plots the best fit lines as determined by the code
        below the plot of the lines is the residuals from the best fit.
        Analystics about the fit line are supposed to be displayed, as
        seen in the printout, but currently cannot display them with the
        graphs (although it should be possible)
    -Export to html file and display on local host
"""

import becquerel as bq
import numpy as np
import matplotlib.pyplot as plt
import mpld3

plt.rcParams['figure.facecolor'] = 'white'
np.random.seed(0)
spec1 = bq.Spectrum.from_file('../tests/samples/digibase_5min_30_1.spe')
model = (bq.fitting.GaussModel(prefix='gauss0_') +
         bq.fitting.LineModel(prefix='linear_'))
fitter = bq.Fitter(model,
                   x=spec1.bin_indices,
                   y=spec1.counts_vals,
                   y_unc=spec1.counts_uncs,
                   roi=(350, 450))

fitter.fit()
fitter.custom_plot()
mpld3.show()