def simulate_spectrum_dataset(model, random_state=0): energy_edges = np.logspace(-0.5, 1.5, 21) * u.TeV energy_axis = MapAxis.from_edges(energy_edges, interp="log", name="energy") energy_axis_true = energy_axis.copy(name="energy_true") aeff = EffectiveAreaTable2D.from_parametrization( energy_axis_true=energy_axis_true) bkg_model = SkyModel( spectral_model=PowerLawSpectralModel(index=2.5, amplitude="1e-12 cm-2 s-1 TeV-1"), name="background", ) bkg_model.spectral_model.amplitude.frozen = True bkg_model.spectral_model.index.frozen = True geom = RegionGeom.create(region="icrs;circle(0, 0, 0.1)", axes=[energy_axis]) acceptance = RegionNDMap.from_geom(geom=geom, data=1) edisp = EDispKernelMap.from_diagonal_response( energy_axis=energy_axis, energy_axis_true=energy_axis_true, geom=geom, ) geom_true = RegionGeom.create(region="icrs;circle(0, 0, 0.1)", axes=[energy_axis_true]) exposure = make_map_exposure_true_energy(pointing=SkyCoord("0d", "0d"), aeff=aeff, livetime=100 * u.h, geom=geom_true) mask_safe = RegionNDMap.from_geom(geom=geom, dtype=bool) mask_safe.data += True acceptance_off = RegionNDMap.from_geom(geom=geom, data=5) dataset = SpectrumDatasetOnOff( name="test_onoff", exposure=exposure, acceptance=acceptance, acceptance_off=acceptance_off, edisp=edisp, mask_safe=mask_safe, ) dataset.models = bkg_model bkg_npred = dataset.npred_signal() dataset.models = model dataset.fake( random_state=random_state, npred_background=bkg_npred, ) return dataset
def hess_datasets(): datasets = Datasets([]) pwl = PowerLawSpectralModel(amplitude="3.5e-11 cm-2s-1TeV-1", index=2.7) model = SkyModel(spectral_model=pwl, name="Crab") for obsid in [23523, 23526]: dataset = SpectrumDatasetOnOff.from_ogip_files( f"$GAMMAPY_DATA/joint-crab/spectra/hess/pha_obs{obsid}.fits") dataset.models = model datasets.append(dataset) return datasets
def test_energy_flux_error_PowerLaw(): emin = 1 * u.TeV emax = 10 * u.TeV powerlaw = PowerLawSpectralModel() powerlaw.parameters['index'].error = 0.4 powerlaw.parameters['amplitude'].error = 1e-13 enrg_flux, enrg_flux_error = powerlaw.energy_flux_error(emin,emax) assert_allclose(enrg_flux.value/1e-12, 2.303, rtol=0.001) assert_allclose(enrg_flux_error.value/1e-12, 1.347, rtol=0.001)
def test_stacked_fit(self): dataset = self.datasets[0].copy() dataset.stack(self.datasets[1]) dataset.models = SkyModel(PowerLawSpectralModel()) 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_flux_points_plot_no_error_bar(): table = Table() pwl = PowerLawSpectralModel() e_ref = np.geomspace(1, 100, 7) * u.TeV table["e_ref"] = e_ref table["dnde"] = pwl(e_ref) table.meta["SED_TYPE"] = "dnde" flux_points = FluxPoints.from_table(table) with mpl_plot_check(): flux_points.plot(sed_type="flux")
def data_prep(): data_store = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/") OBS_ID = 23523 obs_ids = OBS_ID * np.ones(N_OBS) observations = data_store.get_observations(obs_ids) time_intervals = [(obs.tstart, obs.tstop) for obs in observations] target_position = SkyCoord(ra=83.63308, dec=22.01450, unit="deg") e_reco = MapAxis.from_bounds(0.1, 40, nbin=40, interp="log", unit="TeV").edges e_true = MapAxis.from_bounds(0.05, 100, nbin=200, interp="log", unit="TeV").edges on_region_radius = Angle("0.11 deg") on_region = CircleSkyRegion(center=target_position, radius=on_region_radius) dataset_maker = SpectrumDatasetMaker(region=on_region, e_reco=e_reco, e_true=e_true, containment_correction=True) bkg_maker = ReflectedRegionsBackgroundMaker() safe_mask_masker = SafeMaskMaker(methods=["aeff-max"], aeff_percent=10) spectral_model = PowerLawSpectralModel(index=2.6, amplitude=2.0e-11 * u.Unit("1 / (cm2 s TeV)"), reference=1 * u.TeV) spectral_model.index.frozen = False model = spectral_model.copy() model.name = "crab" datasets_1d = [] for time_interval in time_intervals: observation = observations.select_time(time_interval)[0] dataset = dataset_maker.run(observation, selection=["counts", "aeff", "edisp"]) dataset_on_off = bkg_maker.run(dataset, observation) dataset_on_off = safe_mask_masker.run(dataset_on_off, observation) datasets_1d.append(dataset_on_off) for dataset in datasets_1d: model = spectral_model.copy() model.name = "crab" dataset.model = model return datasets_1d
def test_integrate_spectrum(): """ Test numerical integration against analytical solution. """ emin = Quantity(1, "TeV") emax = Quantity(10, "TeV") pwl = PowerLawSpectralModel(index=2.3) ref = pwl.integral(emin=emin, emax=emax) val = integrate_spectrum(pwl, emin, emax) assert_quantity_allclose(val, ref)
def test_energy_flux_error_power_law(): energy_min = 1 * u.TeV energy_max = 10 * u.TeV powerlaw = PowerLawSpectralModel() powerlaw.parameters["index"].error = 0.4 powerlaw.parameters["amplitude"].error = 1e-13 enrg_flux, enrg_flux_error = powerlaw.energy_flux_error( energy_min, energy_max) assert_allclose(enrg_flux.value / 1e-12, 2.303, rtol=0.001) assert_allclose(enrg_flux_error.value / 1e-12, 1.085, rtol=0.001)
def test_energy_dependent_model(): axis = MapAxis.from_edges(np.logspace(-1, 1, 4), unit=u.TeV, name="energy_true") geom_true = WcsGeom.create( skydir=(0, 0), binsz="0.1 deg", npix=(50, 50), frame="galactic", axes=[axis] ) spectral_model = PowerLawSpectralModel(amplitude="1e-11 cm-2 s-1 TeV-1") spatial_model = MyCustomGaussianModel(frame="galactic") sky_model = SkyModel(spectral_model=spectral_model, spatial_model=spatial_model) model = sky_model.integrate_geom(geom_true) assert_allclose(model.data.sum(), 9.9e-11, rtol=1e-3)
def test_lightcurve_estimator_spectrum_datasets(): # Doing a LC on one hour bin datasets = get_spectrum_datasets() time_intervals = [ Time(["2010-01-01T00:00:00", "2010-01-01T01:00:00"]), Time(["2010-01-01T01:00:00", "2010-01-01T02:00:00"]), ] estimator = LightCurveEstimator( energy_edges=[1, 30] * u.TeV, norm_n_values=3, time_intervals=time_intervals, selection_optional="all", ) lightcurve = estimator.run(datasets) table = lightcurve.to_table(format="lightcurve") assert_allclose(table["time_min"], [55197.0, 55197.041667]) assert_allclose(table["time_max"], [55197.041667, 55197.083333]) assert_allclose(table["e_ref"], [[5.623413], [5.623413]]) assert_allclose(table["e_min"], [[1], [1]]) assert_allclose(table["e_max"], [[31.622777], [31.622777]]) assert_allclose( table["ref_dnde"], [[3.162278e-14], [3.162278e-14]], rtol=1e-5 ) assert_allclose( table["ref_flux"], [[9.683772e-13], [9.683772e-13]], rtol=1e-5 ) assert_allclose( table["ref_eflux"], [[3.453878e-12], [3.453878e-12]], rtol=1e-5 ) assert_allclose(table["stat"], [[16.824042], [17.391981]], rtol=1e-5) assert_allclose(table["norm"], [[0.911963], [0.9069318]], rtol=1e-2) assert_allclose(table["norm_err"], [[0.057769], [0.057835]], rtol=1e-2) assert_allclose(table["counts"], [[[791, np.nan]], [[np.nan, 784]]]) assert_allclose(table["norm_errp"], [[0.058398], [0.058416]], rtol=1e-2) assert_allclose(table["norm_errn"], [[0.057144], [0.057259]], rtol=1e-2) assert_allclose(table["norm_ul"], [[1.029989], [1.025061]], rtol=1e-2) assert_allclose(table["sqrt_ts"], [[19.384781], [19.161769]], rtol=1e-2) assert_allclose(table["ts"], [[375.769735], [367.173374]], rtol=1e-2) assert_allclose(table[0]["norm_scan"], [[0.2, 1.0, 5.0]]) assert_allclose( table[0]["stat_scan"], [[224.058304, 19.074405, 2063.75636]], rtol=1e-5, ) # TODO: fix reference model I/O fp = FluxPoints.from_table( table=table, format="lightcurve", reference_model=PowerLawSpectralModel() ) assert fp.norm.geom.axes.names == ["energy", "time"] assert fp.counts.geom.axes.names == ["dataset", "energy", "time"] assert fp.stat_scan.geom.axes.names == ["norm", "energy", "time"]
def read(): datasets = [] model = PowerLawSpectralModel(index=2, amplitude=2e-11 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV) for ind in range(N_OBS): dataset = SpectrumDatasetOnOff.from_ogip_files( filename=f"pha_obs{ind}.fits") dataset.model = model datasets.append(dataset) return datasets
def test_integral_error_PowerLaw(): energy = np.linspace(1 * u.TeV, 10 * u.TeV, 10) emin = energy[:-1] emax = energy[1:] powerlaw = PowerLawSpectralModel() powerlaw.parameters['index'].error = 0.4 powerlaw.parameters['amplitude'].error = 1e-13 flux, flux_error = powerlaw.integral_error(emin, emax) assert_allclose(flux.value[0] / 1e-13, 5.0, rtol=0.1) assert_allclose(flux_error.value[0] / 1e-14, 8.546615432273905, rtol=0.01)
def test_compute_npred_sign(): center = SkyCoord("0 deg", "0 deg", frame="galactic") energy_axis_true = MapAxis.from_energy_bounds(".1 TeV", "10 TeV", nbin=2, name="energy_true") geom = WcsGeom.create(skydir=center, width=1 * u.deg, axes=[energy_axis_true], frame='galactic', binsz=0.2 * u.deg) spectral_model_pos = PowerLawSpectralModel(index=2, amplitude="1e-11 TeV-1 s-1 m-2") spectral_model_neg = PowerLawSpectralModel( index=2, amplitude="-1e-11 TeV-1 s-1 m-2") spatial_model = PointSpatialModel(lon_0=0 * u.deg, lat_0=0 * u.deg, frame="galactic") model_pos = SkyModel(spectral_model=spectral_model_pos, spatial_model=spatial_model) model_neg = SkyModel(spectral_model=spectral_model_neg, spatial_model=spatial_model) exposure = Map.from_geom(geom, unit="m2 s") exposure.data += 1.0 psf = PSFKernel.from_gauss(geom, sigma="0.1 deg") evaluator_pos = MapEvaluator(model=model_pos, exposure=exposure, psf=psf) evaluator_neg = MapEvaluator(model=model_neg, exposure=exposure, psf=psf) npred_pos = evaluator_pos.compute_npred() npred_neg = evaluator_neg.compute_npred() assert (npred_pos.data == -npred_neg.data).all() assert np.all(npred_pos.data >= 0) assert np.all(npred_neg.data <= 0)
def test_no_likelihood_contribution(): dataset = simulate_spectrum_dataset( SkyModel(spectral_model=PowerLawSpectralModel(), name="source")) dataset.mask_safe = RegionNDMap.from_geom(dataset.counts.geom, dtype=bool) fpe = FluxPointsEstimator(e_edges=[1, 3, 10] * u.TeV, source="source") fp = fpe.run([dataset]) assert np.isnan(fp.table["norm"]).all() assert np.isnan(fp.table["norm_err"]).all() assert np.isnan(fp.table["norm_ul"]).all() assert np.isnan(fp.table["norm_scan"]).all() assert_allclose(fp.table["counts"], 0)
def __init__(self, regions, spectrum=None, **kwargs): if len(regions) <= 1: raise ValueError( "Please provide at least two regions for flux profile estimation." ) self.regions = regions if spectrum is None: spectrum = PowerLawSpectralModel() self.spectrum = spectrum super().__init__(**kwargs)
def test_str(self): model = SkyModel(spectral_model=PowerLawSpectralModel()) dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, models=model, exposure=self.aeff * self.livetime, edisp=self.edisp, acceptance=RegionNDMap.from_geom(geom=self.on_counts.geom, data=1), acceptance_off=RegionNDMap.from_geom(geom=self.off_counts.geom, data=10), ) assert "SpectrumDatasetOnOff" in str(dataset) assert "wstat" in str(dataset)
def get_spectrum_datasets(): model = SkyModel(spectral_model=PowerLawSpectralModel()) dataset_1 = simulate_spectrum_dataset(model=model, random_state=0) dataset_1._name = "dataset_1" gti1 = GTI.create("0h", "1h", "2010-01-01T00:00:00") dataset_1.gti = gti1 dataset_2 = simulate_spectrum_dataset(model=model, random_state=1) dataset_2._name = "dataset_2" gti2 = GTI.create("1h", "2h", "2010-01-01T00:00:00") dataset_2.gti = gti2 return [dataset_1, dataset_2]
def test_str(self): model = SkyModel(spectral_model=PowerLawSpectralModel()) dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, models=model, exposure=self.aeff * self.livetime, edisp=self.edisp, acceptance=1, acceptance_off=10, ) assert "SpectrumDatasetOnOff" in str(dataset) assert "wstat" in str(dataset)
def test_integral_error_power_law(): energy = np.linspace(1 * u.TeV, 10 * u.TeV, 10) energy_min = energy[:-1] energy_max = energy[1:] powerlaw = PowerLawSpectralModel() powerlaw.parameters["index"].error = 0.4 powerlaw.parameters["amplitude"].error = 1e-13 flux, flux_error = powerlaw.integral_error(energy_min, energy_max) assert_allclose(flux.value[0] / 1e-13, 5.0, rtol=1e-3) assert_allclose(flux_error.value[0] / 1e-14, 7.915984, rtol=1e-3)
def get_test_cases(): e_true = Quantity(np.logspace(-1, 2, 120), "TeV") e_reco = Quantity(np.logspace(-1, 2, 100), "TeV") return [ dict( model=SkyModel(spectral_model=PowerLawSpectralModel( amplitude="1e-11 TeV-1 cm-2 s-1")), aeff=EffectiveAreaTable.from_parametrization(e_true), livetime="10 h", npred=1448.05960, ), dict( model=SkyModel(spectral_model=PowerLawSpectralModel( reference="1 GeV", amplitude="1e-11 GeV-1 cm-2 s-1")), aeff=EffectiveAreaTable.from_parametrization(e_true), livetime="30 h", npred=4.34417881, ), dict( model=SkyModel(spectral_model=PowerLawSpectralModel( amplitude="1e-11 TeV-1 cm-2 s-1")), aeff=EffectiveAreaTable.from_parametrization(e_true), edisp=EDispKernel.from_gauss(e_reco=e_reco, e_true=e_true, bias=0, sigma=0.2), livetime="10 h", npred=1437.494815, ), dict( model=SkyModel(spectral_model=TemplateSpectralModel( energy=[0.1, 0.2, 0.3, 0.4] * u.TeV, values=[4.0, 3.0, 1.0, 0.1] * u.Unit("TeV-1"), )), aeff=EffectiveAreaTable.from_constant([0.1, 0.2, 0.3, 0.4] * u.TeV, 1), npred=0.554513062, ), ]
def table_psf_in_energy_range(self, energy_range, spectrum=None, n_bins=11, **kwargs): """Average PSF in a given energy band. Expected counts in sub energy bands given the given exposure and spectrum are used as weights. Parameters ---------- energy_range : `~astropy.units.Quantity` Energy band spectrum : `~gammapy.modeling.models.SpectralModel` Spectral model used for weighting the PSF. Default is a power law with index=2. n_bins : int Number of energy points in the energy band, used to compute the weighted PSF. Returns ------- psf : `EnergyDependentTablePSF` Table PSF """ from gammapy.modeling.models import PowerLawSpectralModel, TemplateSpectralModel if spectrum is None: spectrum = PowerLawSpectralModel() exposure = TemplateSpectralModel(self.axes["energy_true"].center, self.exposure) e_min, e_max = energy_range energy = MapAxis.from_energy_bounds(e_min, e_max, n_bins).edges[:, np.newaxis] weights = spectrum(energy) * exposure(energy) weights /= weights.sum() psf_value = self.evaluate(energy_true=energy) psf_value_weighted = weights * psf_value energy_axis = MapAxis.from_edges(energy_range, name="energy_true") data = psf_value_weighted.sum(axis=0, keepdims=True) return self.__class__(axes=[energy_axis, self.axes["rad"]], data=data.value, unit=data.unit, **kwargs)
def test_npred_models(): e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=3) geom = RegionGeom(region=None, axes=[e_reco]) spectrum_dataset = SpectrumDataset.create(geom=geom) spectrum_dataset.exposure.quantity = 1e10 * u.Unit("cm2 h") pwl_1 = PowerLawSpectralModel(index=2) pwl_2 = PowerLawSpectralModel(index=2) model_1 = SkyModel(spectral_model=pwl_1) model_2 = SkyModel(spectral_model=pwl_2) spectrum_dataset.models = Models([model_1, model_2]) npred = spectrum_dataset.npred() assert_allclose(npred.data.sum(), 64.8) npred_sig = spectrum_dataset.npred_signal() assert_allclose(npred_sig.data.sum(), 64.8) npred_sig_model1 = spectrum_dataset.npred_signal(model_name=model_1.name) assert_allclose(npred_sig_model1.data.sum(), 32.4)
def dataset(): path = "$GAMMAPY_DATA/tests/spectrum/flux_points/diff_flux_points.fits" data = FluxPoints.read(path) data.table["e_ref"] = data.e_ref.to("TeV") model = SkyModel(spectral_model=PowerLawSpectralModel( index=2.3, amplitude="2e-13 cm-2 s-1 TeV-1", reference="1 TeV")) obs_table = Table() obs_table["TELESCOP"] = ["CTA"] obs_table["OBS_ID"] = ["0001"] obs_table["INSTRUME"] = ["South_Z20_50h"] dataset = FluxPointsDataset(model, data, meta_table=obs_table) return dataset
def test_plot_fit(self): model = SkyModel(spectral_model=PowerLawSpectralModel()) dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, models=model, aeff=self.aeff, livetime=self.livetime, edisp=self.edisp, acceptance=1, acceptance_off=10, ) with mpl_plot_check(): dataset.plot_fit()
def test_integral_exp_cut_off_power_law_large_number_of_bins(): energy = np.geomspace(1, 10, 100) * u.TeV energy_min = energy[:-1] energy_max = energy[1:] exppowerlaw = ExpCutoffPowerLawSpectralModel( amplitude="1e-11 TeV-1 cm-2 s-1", index=2) exppowerlaw.parameters["lambda_"].value = 1e-3 powerlaw = PowerLawSpectralModel(amplitude="1e-11 TeV-1 cm-2 s-1", index=2) expected_flux = powerlaw.integral(energy_min, energy_max) flux = exppowerlaw.integral(energy_min, energy_max) assert_allclose(flux.value, expected_flux.value, rtol=0.01)
def define_model_3d(target_position): spatial_model = PointSpatialModel(lon_0=target_position.ra, lat_0=target_position.dec, frame="icrs") spectral_model = PowerLawSpectralModel( index=3.4, amplitude=2e-11 * u.Unit("1 / (cm2 s TeV)"), reference=1 * u.TeV, ) spectral_model.parameters["index"].frozen = False sky_model = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model, name="pks2155") return sky_model
def simulate_spectrum_dataset(model, random_state=0): energy = np.logspace(-0.5, 1.5, 21) * u.TeV aeff = EffectiveAreaTable.from_parametrization(energy=energy) bkg_model = PowerLawSpectralModel(index=2.5, amplitude="1e-12 cm-2 s-1 TeV-1") dataset = SpectrumDatasetOnOff( aeff=aeff, model=model, livetime=100 * u.h, acceptance=1, acceptance_off=5 ) eval = SpectrumEvaluator(model=bkg_model, aeff=aeff, livetime=100 * u.h) bkg_model = eval.compute_npred() dataset.fake(random_state=random_state, background_model=bkg_model) return dataset
def sky_model(): spatial_model = GaussianSpatialModel( lon_0="3 deg", lat_0="4 deg", sigma="3 deg", frame="galactic" ) spectral_model = PowerLawSpectralModel( index=2, amplitude="1e-11 cm-2 s-1 TeV-1", reference="1 TeV" ) temporal_model = ConstantTemporalModel() return SkyModel( spatial_model=spatial_model, spectral_model=spectral_model, temporal_model=temporal_model, name="source-1", )
def compute_npreds(datasets, n_iter, n_src): models = Models() positions = np.random.uniform(-4., 4., (n_src, 2)) for pos in positions: pos = u.Quantity(pos, "deg") model = SkyModel(spectral_model=PowerLawSpectralModel(), spatial_model=GaussianSpatialModel(lon_0=pos[0], lat_0=pos[1], sigma="0.5 deg")) models.append(model) for i in range(n_iter): datasets.models = models tmp = datasets[0].npred()
def test_flux_points_estimator_small_edges(): pl = PowerLawSpectralModel(amplitude="1e-11 cm-2s-1TeV-1") datasets, fpe = create_fpe(pl) fpe.energy_edges = datasets[0].counts.geom.axes["energy"].upsample( 3).edges[1:4] fpe.selection_optional = [] fp = fpe.run(datasets) assert_allclose(fp.ts.data[0, 0, 0], 2156.96959291) assert np.isnan(fp.ts.data[1, 0, 0]) assert np.isnan(fp.npred.data[1, 0, 0])