def test_solid_angle_compound(): center1 = SkyCoord(ra=0 * u.deg, dec=0 * u.deg) center2 = SkyCoord(ra=3 * u.deg, dec=0 * u.deg) region1 = CircleSkyRegion(center1, radius=1 * u.deg) region2 = CircleSkyRegion(center2, radius=1 * u.deg) # regions don't overlap, so expected area is the sum of both region = region1 | region2 expected = sum( RegionGeom.create(r).solid_angle() for r in [region1, region2]) geom = RegionGeom.create(region) omega = geom.solid_angle() assert u.isclose(omega, expected, rtol=2e-3) region1 = CircleSkyRegion(center1, radius=5 * u.deg) region2 = CircleSkyRegion(center2, radius=1 * u.deg) # fully overlapping regions, expect only area of the larger one expected = RegionGeom.create(region1).solid_angle() region = region1 | region2 assert isinstance(region, CompoundSkyRegion) geom = RegionGeom.create(region) omega = geom.solid_angle() assert u.isclose(omega, expected, rtol=2e-3)
def test_eq(region): axis = MapAxis.from_edges([1, 10] * u.TeV, name="energy", interp="log") geom_1 = RegionGeom.create(region, axes=[axis]) geom_2 = RegionGeom.create(region, axes=[axis]) assert geom_1 == geom_2 axis = MapAxis.from_edges([1, 100] * u.TeV, name="energy", interp="log") geom_3 = RegionGeom.create(region, axes=[axis]) assert not geom_2 == geom_3
def test_create_axis(region, energy_axis, test_axis): geom = RegionGeom.create(region, axes=[energy_axis]) assert geom.ndim == 3 assert len(geom.axes) == 1 assert geom.data_shape == (3, 1, 1) geom = RegionGeom.create(region, axes=[energy_axis, test_axis]) assert geom.ndim == 4 assert len(geom.axes) == 2 assert geom.data_shape == (2, 3, 1, 1)
def test_create_axis(region): axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=3) geom = RegionGeom.create(region, axes=[axis]) assert geom.ndim == 3 assert len(geom.axes) == 1 assert geom.data_shape == (3, 1, 1) with pytest.raises(ValueError): axis = MapAxis.from_nodes([1, 2], name="test") geom = RegionGeom.create(region, axes=[axis])
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 test_get_coord(region, energy_axis, test_axis): geom = RegionGeom.create(region, axes=[energy_axis]) coords = geom.get_coord() assert_allclose(coords.lon, 0) assert_allclose(coords.lat, 0) assert_allclose(coords["energy"].value.squeeze(), [1.467799, 3.162278, 6.812921], rtol=1e-5) geom = RegionGeom.create(region, axes=[energy_axis, test_axis]) coords = geom.get_coord() assert coords["lon"].shape == (2, 3, 1, 1) assert coords["test"].shape == (2, 3, 1, 1) assert_allclose(coords["energy"].value[1].squeeze(), [1.467799, 3.162278, 6.812921], rtol=1e-5) assert_allclose(coords["test"].value[:,1].squeeze(), [1,2], rtol=1e-5)
def test_get_idx(region, energy_axis, test_axis): geom = RegionGeom.create(region, axes=[energy_axis]) pix = geom.get_idx() assert_allclose(pix[0], 0) assert_allclose(pix[1], 0) assert_allclose(pix[2].squeeze(), [0, 1, 2]) geom = RegionGeom.create(region, axes=[energy_axis, test_axis]) pix = geom.get_idx() assert pix[0].shape == (2, 3, 1, 1) assert_allclose(pix[0], 0) assert_allclose(pix[1], 0) assert_allclose(pix[2][0].squeeze(), [0, 1, 2])
def test_defined_wcs(region): wcs = WcsGeom.create(skydir=(0, 0), frame="galactic", width="1.5deg", binsz="0.1deg").wcs geom = RegionGeom.create(region, wcs=wcs) assert geom.binsz_wcs[0].deg == 0.1
def test_solid_angle(region): geom = RegionGeom.create(region) omega = geom.solid_angle() assert omega.unit == "sr" reference = 2 * np.pi * (1 - np.cos(region.radius)) assert_allclose(omega.value, reference.value, rtol=1e-3)
def lightcurve(self): """Lightcurve (`~gammapy.estimators.FluxPoints`).""" time_axis = self.data["time_axis"] tag = "Flux_History" energy_axis = MapAxis.from_energy_edges(self.energy_range) geom = RegionGeom.create(region=self.position, axes=[energy_axis, time_axis]) names = ["flux", "flux_errp", "flux_errn", "flux_ul"] maps = Maps.from_geom(geom=geom, names=names) maps["flux"].quantity = self.data[tag] maps["flux_errp"].quantity = self.data[f"Unc_{tag}"][:, 1] maps["flux_errn"].quantity = -self.data[f"Unc_{tag}"][:, 0] maps["flux_ul"].quantity = compute_flux_points_ul( maps["flux"].quantity, maps["flux_errp"].quantity ) is_ul = np.isnan(maps["flux_errn"]) maps["flux_ul"].data[~is_ul] = np.nan return FluxPoints.from_maps( maps=maps, sed_type="flux", reference_model=self.sky_model(), meta=self.flux_points_meta.copy(), )
def test_upsample(region): axis = MapAxis.from_edges([1, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) geom_up = geom.upsample(factor=2, axis_name="energy") assert_allclose(geom_up.axes[0].edges.value, [1.0, 3.162278, 10.0], rtol=1e-5)
def spectrum_dataset_crab(): e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") e_true = MapAxis.from_edges(np.logspace(-0.5, 2, 11) * u.TeV, name="energy_true") geom = RegionGeom.create( "icrs;circle(83.63, 22.01, 0.11)", axes=[e_reco], binsz_wcs="0.01deg" ) return SpectrumDataset.create(geom=geom, energy_axis_true=e_true)
def test_separation(region): geom = RegionGeom.create(region) position = SkyCoord([0, 0], [0, 1.1], frame="galactic", unit="deg") separation = geom.separation(position) assert_allclose(separation.deg, [0, 1.1])
def test_reflected_bkg_maker_no_off(reflected_bkg_maker, observations, caplog): pos = SkyCoord(83.6333313, 21.51444435, unit="deg", frame="icrs") radius = Angle(0.11, "deg") region = CircleSkyRegion(pos, radius) maker = SpectrumDatasetMaker(selection=["counts"]) datasets = [] e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") e_true = MapAxis.from_edges(np.logspace(-0.5, 2, 11) * u.TeV, name="energy_true") geom = RegionGeom.create(region=region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom, energy_axis_true=e_true) for obs in observations: dataset = maker.run(dataset_empty, obs) dataset_on_off = reflected_bkg_maker.run(dataset, obs) datasets.append(dataset_on_off) assert datasets[0].counts_off is None assert_allclose(datasets[0].acceptance_off, 0) assert_allclose(datasets[0].mask_safe.data, False) assert "WARNING" in [record.levelname for record in caplog.records] message1 = f"ReflectedRegionsBackgroundMaker failed. " \ f"No OFF region found outside exclusion mask for {datasets[0].name}." message2 = f"ReflectedRegionsBackgroundMaker failed. " \ f"Setting {datasets[0].name} mask to False." assert message1 in [record.message for record in caplog.records] assert message2 in [record.message for record in caplog.records]
def test_contributes_region_mask(): axis = MapAxis.from_edges(np.logspace(-1, 1, 3), unit=u.TeV, name="energy") geom = RegionGeom.create("galactic;circle(0, 0, 0.2)", axes=[axis], binsz_wcs="0.05 deg") mask = Map.from_geom(geom, unit="", dtype="bool") mask.data[...] = True spatial_model1 = GaussianSpatialModel(lon_0="0.2 deg", lat_0="0 deg", sigma="0.1 deg", frame="galactic") spatial_model2 = PointSpatialModel(lon_0="0.3 deg", lat_0="0.3 deg", frame="galactic") model1 = SkyModel( spatial_model=spatial_model1, spectral_model=PowerLawSpectralModel(), name="source-1", ) model2 = SkyModel( spatial_model=spatial_model2, spectral_model=PowerLawSpectralModel(), name="source-2", ) assert model1.contributes(mask, margin=0 * u.deg) assert not model2.contributes(mask, margin=0 * u.deg) assert model2.contributes(mask, margin=0.3 * u.deg)
def make_counts_off(self, dataset, observation): """Make off counts. Parameters ---------- dataset : `SpectrumDataset` Spectrum dataset. observation : `DatastoreObservation` Data store observation. Returns ------- counts_off : `RegionNDMap` Off counts. """ finder = self._get_finder(dataset, observation) finder.run() energy_axis = dataset.counts.geom.axes["energy"] if len(finder.reflected_regions) > 0: region_union = list_to_compound_region(finder.reflected_regions) wcs = finder.reference_map.geom.wcs geom = RegionGeom.create(region=region_union, axes=[energy_axis], wcs=wcs) counts_off = RegionNDMap.from_geom(geom=geom) counts_off.fill_events(observation.events) acceptance_off = len(finder.reflected_regions) else: # if no OFF regions are found, off is set to None and acceptance_off to zero counts_off = None acceptance_off = 0 return counts_off, acceptance_off
def _create_region_geometry(on_region_settings, axes): """Create the region geometry.""" on_lon = on_region_settings.lon on_lat = on_region_settings.lat on_center = SkyCoord(on_lon, on_lat, frame=on_region_settings.frame) on_region = CircleSkyRegion(on_center, on_region_settings.radius) return RegionGeom.create(region=on_region, axes=axes)
def test_get_coord(region): axis = MapAxis.from_edges([1, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) coords = geom.get_coord() assert_allclose(coords.lon, 0) assert_allclose(coords.lat, 0) assert_allclose(coords["energy"].value, 3.162278, rtol=1e-5)
def test_centers(region): geom = RegionGeom.create(region) assert_allclose(geom.center_skydir.l.deg, 0) assert_allclose(geom.center_skydir.b.deg, 0) assert_allclose(geom.center_pix, (0, 0)) values = [_.value for _ in geom.center_coord] assert_allclose(values, (0, 0))
def test_get_idx(region): axis = MapAxis.from_edges([1, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) pix = geom.get_idx() assert_allclose(pix[0], 0) assert_allclose(pix[1], 0) assert_allclose(pix[2], 0)
def test_repr(region): axis = MapAxis.from_edges([1, 3.162278, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) assert "RegionGeom" in repr(geom) assert "CircleSkyRegion" in repr(geom)
def test_bin_volume(region): axis = MapAxis.from_edges([1, 3] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) volume = geom.bin_volume() assert volume.unit == "sr TeV" reference = 2 * 2 * np.pi * (1 - np.cos(region.radius)) assert_allclose(volume.value, reference.value, rtol=1e-3)
def test_region_geom_to_from_hdu(region): axis1 = MapAxis.from_edges([1, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis1]) hdulist = geom.to_hdulist(format="ogip") new_geom = RegionGeom.from_hdulist(hdulist, format="ogip") assert new_geom == geom assert new_geom.region.meta["include"]
def test_to_cube_to_image(region): axis = MapAxis.from_edges([1, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region) geom_cube = geom.to_cube([axis]) assert geom_cube.ndim == 3 geom = geom_cube.to_image() assert geom.ndim == 2
def test_coord_to_pix(region, energy_axis, test_axis): geom = RegionGeom.create(region, axes=[energy_axis]) position = SkyCoord(0, 0, frame="galactic", unit="deg") coords = {"skycoord": position, "energy": 1 * u.TeV} coords_pix = geom.coord_to_pix(coords) assert_allclose(coords_pix[0], 0) assert_allclose(coords_pix[1], 0) assert_allclose(coords_pix[2], -0.5) geom = RegionGeom.create(region, axes=[energy_axis, test_axis]) coords["test"] = 2 coords_pix = geom.coord_to_pix(coords) assert_allclose(coords_pix[0], 0) assert_allclose(coords_pix[1], 0) assert_allclose(coords_pix[2], -0.5) assert_allclose(coords_pix[3], 1)
def test_coord_to_pix(region): axis = MapAxis.from_edges([1, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) position = SkyCoord(0, 0, frame="galactic", unit="deg") coords = {"skycoord": position, "energy": 1 * u.TeV} coords_pix = geom.coord_to_pix(coords) assert_allclose(coords_pix[0], 0) assert_allclose(coords_pix[1], 0) assert_allclose(coords_pix[2], -0.5)
def test_spectrum_dataset_maker_hess_dl3(spectrum_dataset_crab, observations_hess_dl3): datasets = [] maker = SpectrumDatasetMaker(use_region_center=False) datasets = [] for obs in observations_hess_dl3: dataset = maker.run(spectrum_dataset_crab, obs) datasets.append(dataset) # Exposure assert_allclose(datasets[0].exposure.data.sum(), 7374718644.757894) assert_allclose(datasets[1].exposure.data.sum(), 6691006466.659032) # Background assert_allclose(datasets[0].npred_background().data.sum(), 7.7429157, rtol=1e-5) assert_allclose(datasets[1].npred_background().data.sum(), 5.7314076, rtol=1e-5) # Compare background with using bigger region e_reco = datasets[0].background.geom.axes["energy"] e_true = datasets[0].exposure.geom.axes["energy_true"] geom_bigger = RegionGeom.create("icrs;circle(83.63, 22.01, 0.22)", axes=[e_reco]) datasets_big_region = [] bigger_region_dataset = SpectrumDataset.create( geom=geom_bigger, energy_axis_true=e_true ) for obs in observations_hess_dl3: dataset = maker.run(bigger_region_dataset, obs) datasets_big_region.append(dataset) ratio_regions = ( datasets[0].counts.geom.solid_angle() / datasets_big_region[1].counts.geom.solid_angle() ) ratio_bg_1 = ( datasets[0].npred_background().data.sum() / datasets_big_region[0].npred_background().data.sum() ) ratio_bg_2 = ( datasets[1].npred_background().data.sum() / datasets_big_region[1].npred_background().data.sum() ) assert_allclose(ratio_bg_1, ratio_regions, rtol=1e-2) assert_allclose(ratio_bg_2, ratio_regions, rtol=1e-2) # Edisp -> it isn't exactly 8, is that right? it also isn't without averaging assert_allclose( datasets[0].edisp.edisp_map.data[:, :, 0, 0].sum(), e_reco.nbin * 2, rtol=1e-1 ) assert_allclose( datasets[1].edisp.edisp_map.data[:, :, 0, 0].sum(), e_reco.nbin * 2, rtol=1e-1 )
def test_pix_to_coord_2axes(region, energy_axis, test_axis): geom = RegionGeom.create(region, axes=[energy_axis, test_axis]) pix = (0, 0, 0, 0) coords = geom.pix_to_coord(pix) assert_allclose(coords[0].value, 0) assert_allclose(coords[1].value, 0) assert_allclose(coords[2].value, 1.467799, rtol=1e-5) assert_allclose(coords[3].value, 1) pix = (0, 0, 0, 2) coords = geom.pix_to_coord(pix) assert_allclose(coords[3].value, 3)
def region_map_flux_estimate(): axis = MapAxis.from_energy_edges((0.1, 1.0, 10.0), unit="TeV") geom = RegionGeom.create("galactic;circle(0, 0, 0.1)", axes=[axis]) maps = Maps.from_geom( geom=geom, names=["norm", "norm_err", "norm_errn", "norm_errp", "norm_ul"]) maps["norm"].data = np.array([1.0, 1.0]) maps["norm_err"].data = np.array([0.1, 0.1]) maps["norm_errn"].data = np.array([0.2, 0.2]) maps["norm_errp"].data = np.array([0.15, 0.15]) maps["norm_ul"].data = np.array([2.0, 2.0]) return maps
def test_pix_to_coord(region): axis = MapAxis.from_edges([1, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) pix = (0, 0, 0) coords = geom.pix_to_coord(pix) assert_allclose(coords[0].value, 0) assert_allclose(coords[1].value, 0) assert_allclose(coords[2].value, 3.162278, rtol=1e-5) pix = (1, 1, 1) coords = geom.pix_to_coord(pix) assert_allclose(coords[0].value, np.nan) assert_allclose(coords[1].value, np.nan) assert_allclose(coords[2].value, 31.62278, rtol=1e-5)