Beispiel #1
0
def run_gammapy_fit(obs_list, fit_range, eval_contours=None):
    """Run fit with Gammapy, using iminiuit"""
    model_lp = Log10Parabola(
        amplitude=3.80 * 1e-11 * u.Unit("cm-2 s-1 TeV-1"),
        reference=1 * u.Unit("TeV"),
        alpha=2.47 * u.Unit(""),
        beta=0.24 * u.Unit(""),
    )

    # note this step is very important to iminuit, to initialize the parameter error!
    fit = SpectrumFit(obs_list=obs_list, model=model_lp, fit_range=fit_range)

    log.info("Starting fit ...")
    t = time()
    fit.optimize(backend="minuit", pedantic=True)
    fit.run()
    t = time() - t
    log.info(f"Finished fit in {t} seconds.")

    results = extract_spectrum_results_gammapy(fit)
    print(fit.result[0])

    if eval_contours is not None:
        log.info("storing likelihood contours ...")
        # points along the contour
        like_points = 80
        sigma = 1.

        log.info(f"computing amplitude vs alpha {sigma} sigma contour")
        cont = fit.minuit.mncontour("par_000_amplitude",
                                    "par_002_alpha",
                                    numpoints=like_points,
                                    sigma=sigma)
        # the third element of mncontour's returned object is a list of tuples with the contour coordinates
        # (x_1,y_1), ..., (x_n, y_n)]
        cont = np.asarray(cont[2])
        amplitude = cont.T[0]  # transpose and take the first row
        alpha = cont.T[1]  # transpose and take the
        # trick to make a close circle when plotting: just repeat the first coordinate
        amplitude = np.append(amplitude, amplitude[0])
        alpha = np.append(alpha, alpha[0])
        contour_amplitude_alpha = {"amplitude": amplitude, "alpha": alpha}

        log.info(f"computing amplitude vs beta {sigma} sigma contour")
        cont = fit.minuit.mncontour("par_000_amplitude",
                                    "par_003_beta",
                                    numpoints=like_points,
                                    sigma=sigma)
        cont = np.asarray(cont[2])
        amplitude = cont.T[0]  # transpose and take the first row
        beta = cont.T[1]  # transpose and take the
        # trick to make a close circle when plotting: just repeat the first coordinate
        amplitude = np.append(amplitude, amplitude[0])
        beta = np.append(beta, beta[0])
        contour_amplitude_beta = {"amplitude": amplitude, "beta": beta}

        log.info(f"computing alpha vs beta {sigma} sigma contour")
        cont = fit.minuit.mncontour("par_002_alpha",
                                    "par_003_beta",
                                    numpoints=like_points,
                                    sigma=sigma)
        cont = np.asarray(cont[2])
        alpha = cont.T[0]  # transpose and take the first row
        beta = cont.T[1]  # transpose and take the
        # trick to make a close circle when plotting: just repeat the first coordinate
        alpha = np.append(alpha, alpha[0])
        beta = np.append(beta, beta[0])
        contour_alpha_beta = {"alpha": alpha, "beta": beta}

        # define the general dictionary and dump it in a .npy object
        contours = {
            "contour_amplitude_alpha": contour_amplitude_alpha,
            "contour_amplitude_beta": contour_amplitude_beta,
            "contour_alpha_beta": contour_alpha_beta,
        }
        logging.info(f"storing .yaml with contours in {eval_contours}")
        path = Path(eval_contours)
        path.mkdir(parents=True, exist_ok=True)
        np.save(f"{eval_contours}/fit_{sigma}_sigma_contours_logparabola.npy",
                contours)

        return results