def test_map_fit_one_energy_bin(sky_model, geom_image): dataset = get_map_dataset(sky_model, geom_image, geom_image) sky_model.spectral_model.index.value = 3.0 sky_model.spectral_model.index.frozen = True dataset.background_model.norm.value = 0.5 dataset.counts = dataset.npred() # Move a bit away from the best-fit point, to make sure the optimiser runs sky_model.parameters["sigma"].value = 0.21 dataset.background_model.parameters["norm"].frozen = True fit = Fit(dataset) result = fit.run() assert result.success npred = dataset.npred().data.sum() assert_allclose(npred, 1087.073518, rtol=1e-3) assert_allclose(result.total_stat, 5177.19198, rtol=1e-3) pars = result.parameters assert_allclose(pars["lon_0"].value, 0.2, rtol=1e-2) assert_allclose(pars.error("lon_0"), 0.04623, rtol=1e-2) assert_allclose(pars["sigma"].value, 0.2, rtol=1e-2) assert_allclose(pars.error("sigma"), 0.031759, rtol=1e-2) assert_allclose(pars["amplitude"].value, 1e-11, rtol=1e-2) assert_allclose(pars.error("amplitude"), 2.163318e-12, rtol=1e-2)
def test_ecpl_fit(self): self.set_model(self.ecpl) fit = Fit(self.obs_list[0]) fit.run() actual = fit.datasets.parameters["lambda_"].quantity assert actual.unit == "TeV-1" assert_allclose(actual.value, 0.145215, rtol=1e-2)
def test_likelihood_profile_reoptimize(): dataset = MyDataset() fit = Fit(dataset) fit.run() dataset.parameters["y"].value = 0 result = fit.likelihood_profile("x", nvalues=3, reoptimize=True) assert_allclose(result["values"], [0, 2, 4], atol=1e-7) assert_allclose(result["likelihood"], [4, 0, 4], atol=1e-7)
def test_joint_fit(self): self.set_model(self.pwl) fit = Fit(self.obs_list) fit.run() actual = fit.datasets.parameters["index"].value assert_allclose(actual, 2.7806, rtol=1e-3) actual = fit.datasets.parameters["amplitude"].quantity assert actual.unit == "cm-2 s-1 TeV-1" assert_allclose(actual.value, 5.200e-11, rtol=1e-3)
def test_likelihood_profile(): dataset = MyDataset() fit = Fit(dataset) fit.run() result = fit.likelihood_profile("x", nvalues=3) assert_allclose(result["values"], [0, 2, 4], atol=1e-7) assert_allclose(result["likelihood"], [4, 0, 4], atol=1e-7) # Check that original value state wasn't changed assert_allclose(dataset.parameters["x"].value, 2)
def test_compound(self): model = self.pwl * 2 self.set_model(model) fit = Fit(self.obs_list[0]) fit.run() pars = fit.datasets.parameters assert_allclose(pars["index"].value, 2.8166, rtol=1e-3) p = pars["amplitude"] assert p.unit == "cm-2 s-1 TeV-1" assert_allclose(p.value, 5.0714e-12, rtol=1e-3)
def test_stats(self): dataset = self.obs_list[0] dataset.model = self.pwl fit = Fit([dataset]) result = fit.run() stats = dataset.likelihood_per_bin() actual = np.sum(stats[dataset.mask_safe]) desired = result.total_stat assert_allclose(actual, desired)
def test_likelihood_profile(self): dataset = SpectrumDataset( model=self.source_model, counts=self.src, mask_safe=np.ones(self.src.energy.nbin, dtype=bool), ) fit = Fit([dataset]) result = fit.run() true_idx = result.parameters["index"].value values = np.linspace(0.95 * true_idx, 1.05 * true_idx, 100) profile = fit.likelihood_profile("index", values=values) actual = values[np.argmin(profile["likelihood"])] assert_allclose(actual, true_idx, rtol=0.01)
def test_stacked_fit(self): obs_stacker = SpectrumDatasetOnOffStacker(self.obs_list) obs_stacker.run() dataset = obs_stacker.stacked_obs dataset.model = self.pwl fit = Fit([dataset]) result = fit.run() pars = result.parameters assert_allclose(pars["index"].value, 2.7767, rtol=1e-3) assert u.Unit(pars["amplitude"].unit) == "cm-2 s-1 TeV-1" assert_allclose(pars["amplitude"].value, 5.191e-11, rtol=1e-3)
def test_no_edisp(self): dataset = self.obs_list[0] # Bring aeff in RECO space energy = dataset.counts.energy.center data = dataset.aeff.data.evaluate(energy=energy) e_edges = dataset.counts.energy.edges dataset.aeff = EffectiveAreaTable(data=data, energy_lo=e_edges[:-1], energy_hi=e_edges[1:]) dataset.edisp = None dataset.model = self.pwl fit = Fit([dataset]) result = fit.run() assert_allclose(result.parameters["index"].value, 2.7961, atol=0.02)
def test_cash(self): """Simple CASH fit to the on vector""" fit = Fit(self.dataset) result = fit.run() assert result.success assert "minuit" in repr(result) npred = self.dataset.npred().data.sum() assert_allclose(npred, self.npred.sum(), rtol=1e-3) assert_allclose(result.total_stat, -18087404.624, rtol=1e-3) pars = result.parameters assert_allclose(pars["index"].value, 2.1, rtol=1e-2) assert_allclose(pars.error("index"), 0.00127, rtol=1e-2) assert_allclose(pars["amplitude"].value, 1e5, rtol=1e-3) assert_allclose(pars.error("amplitude"), 153.450, rtol=1e-2)
def test_cash(self): """Simple CASH fit to the on vector""" dataset = SpectrumDataset(model=self.source_model, counts=self.src) npred = dataset.npred().data assert_allclose(npred[5], 660.5171, rtol=1e-5) stat_val = dataset.likelihood() assert_allclose(stat_val, -107346.5291, rtol=1e-5) self.source_model.parameters["index"].value = 1.12 fit = Fit([dataset]) result = fit.run() # These values are check with sherpa fits, do not change pars = result.parameters assert_allclose(pars["index"].value, 1.995525, rtol=1e-3) assert_allclose(pars["amplitude"].value, 100245.9, rtol=1e-3)
def setup(self): path = "$GAMMAPY_DATA/joint-crab/spectra/hess/" obs1 = SpectrumDatasetOnOff.from_ogip_files(path + "pha_obs23523.fits") obs2 = SpectrumDatasetOnOff.from_ogip_files(path + "pha_obs23592.fits") self.obs_list = [obs1, obs2] self.pwl = PowerLaw(index=2, amplitude=1e-12 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV) self.ecpl = ExponentialCutoffPowerLaw( index=2, amplitude=1e-12 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV, lambda_=0.1 / u.TeV, ) # Example fit for one observation self.obs_list[0].model = self.pwl self.fit = Fit(self.obs_list[0])
def test_wstat(self): """WStat with on source and background spectrum""" on_vector = self.src.copy() on_vector.data += self.bkg.data obs = SpectrumDatasetOnOff( counts=on_vector, counts_off=self.off, acceptance=1, acceptance_off=1 / self.alpha, ) obs.model = self.source_model self.source_model.parameters.index = 1.12 fit = Fit(obs) result = fit.run() pars = self.source_model.parameters assert_allclose(pars["index"].value, 1.997342, rtol=1e-3) assert_allclose(pars["amplitude"].value, 100245.187067, rtol=1e-3) assert_allclose(result.total_stat, 30.022316, rtol=1e-3)
# Now we'll fit a model to the spectrum with the `Fit` class. First we load a power law model with an initial value for the index and the amplitude and then wo do a likelihood fit. The fit results are printed below. # In[ ]: model = PowerLaw(index=4, amplitude="1.3e-9 cm-2 s-1 TeV-1", reference="0.02 TeV") emin_fit, emax_fit = (0.04 * u.TeV, 0.4 * u.TeV) for obs in extraction.spectrum_observations: obs.model = model obs.mask_fit = obs.counts.energy_mask(emin=emin_fit, emax=emax_fit) joint_fit = Fit(extraction.spectrum_observations) joint_result = joint_fit.run() model.parameters.covariance = joint_result.parameters.covariance print(joint_result) # Now you might want to do the stacking here even if in our case there is only one observation which makes it superfluous. # We can compute flux points by fitting the norm of the global model in energy bands. # In[ ]: e_edges = np.logspace(np.log10(0.04), np.log10(0.4), 7) * u.TeV from gammapy.spectrum import SpectrumDatasetOnOffStacker stacker = SpectrumDatasetOnOffStacker(extraction.spectrum_observations)