def test_reflected_bkg_maker_with_wobble_finder(on_region, observations, exclusion_mask): datasets = [] reflected_bkg_maker = ReflectedRegionsBackgroundMaker( region_finder=WobbleRegionsFinder(n_off_regions=3), exclusion_mask=exclusion_mask, ) e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") geom = RegionGeom(region=on_region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom) spectrum_dataset_maker = SpectrumDatasetMaker(selection=["counts"]) for obs in observations: dataset = spectrum_dataset_maker.run(dataset_empty, obs) dataset_on_off = reflected_bkg_maker.run(dataset, obs) datasets.append(dataset_on_off) regions_0 = compound_region_to_regions(datasets[0].counts_off.geom.region) regions_1 = compound_region_to_regions(datasets[1].counts_off.geom.region) assert_allclose(len(regions_0), 3) assert_allclose(len(regions_1), 3)
def make_counts_off_rad_max(geom_off, rad_max, events): """Extract the OFF counts from a list of point regions and given rad max. This methods does **not** check for overlap of the regions defined by rad_max. Parameters ---------- geom_off: `~gammapy.maps.RegionGeom` reference map geom for the on region rad_max: `~gammapy.irf.RadMax2D` the RAD_MAX_2D table IRF events: `~gammapy.data.EventList` event list to be used to compute the OFF counts Returns ------- counts_off : `~gammapy.maps.RegionNDMap` OFF Counts vs estimated energy extracted from the ON region. """ if not geom_off.is_all_point_sky_regions: raise ValueError( f"Only supports PointSkyRegions, got {geom_off.region} instead") counts_off = RegionNDMap.from_geom(geom=geom_off) for off_region in compound_region_to_regions(geom_off.region): selected_events = events.select_rad_max(rad_max=rad_max, position=off_region.center) counts_off.fill_events(selected_events) return counts_off
def test_to_from_ogip_files(self, tmp_path): dataset = self.dataset.copy(name="test") dataset.write(tmp_path / "test.fits") newdataset = SpectrumDatasetOnOff.read(tmp_path / "test.fits") expected_regions = compound_region_to_regions(self.off_counts.geom.region) regions = compound_region_to_regions(newdataset.counts_off.geom.region) assert newdataset.counts.meta["RESPFILE"] == "test_rmf.fits" assert newdataset.counts.meta["BACKFILE"] == "test_bkg.fits" assert newdataset.counts.meta["ANCRFILE"] == "test_arf.fits" assert_allclose(self.on_counts.data, newdataset.counts.data) assert_allclose(self.off_counts.data, newdataset.counts_off.data) assert_allclose(self.edisp.edisp_map.data, newdataset.edisp.edisp_map.data) assert_time_allclose(newdataset.gti.time_start, dataset.gti.time_start) assert len(regions) == len(expected_regions) assert regions[0].center.is_equivalent_frame(expected_regions[0].center) assert_allclose(regions[1].angle, expected_regions[1].angle)
def _rectangle_bbox(self): if self.region is None: raise ValueError("Region definition required.") regions = compound_region_to_regions(self.region) regions_pix = [_.to_pixel(self.wcs) for _ in regions] bbox = regions_pix[0].bounding_box for region_pix in regions_pix[1:]: bbox = bbox.union(region_pix.bounding_box) rectangle_pix = bbox.to_region() return rectangle_pix.to_sky(self.wcs)
def test_reflected_bkg_maker(on_region, reflected_bkg_maker, observations): 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(region=on_region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom, energy_axis_true=e_true) maker = SpectrumDatasetMaker(selection=["counts"]) 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_allclose(datasets[0].counts_off.data.sum(), 76) assert_allclose(datasets[1].counts_off.data.sum(), 60) regions_0 = compound_region_to_regions(datasets[0].counts_off.geom.region) regions_1 = compound_region_to_regions(datasets[1].counts_off.geom.region) assert_allclose(len(regions_0), 11) assert_allclose(len(regions_1), 11)
def _to_region_table(self): """Export region to a FITS region table.""" if self.region is None: raise ValueError("Region definition required.") # TODO: make this a to_hdulist() method region_list = compound_region_to_regions(self.region) pixel_region_list = [] for reg in region_list: pixel_region_list.append(reg.to_pixel(self.wcs)) table = Regions(pixel_region_list).serialize(format="fits") header = WcsGeom(wcs=self.wcs, npix=self.wcs.array_shape).to_header() table.meta.update(header) return table
def plot_region(self, ax=None, **kwargs): """Plot region in the sky. Parameters ---------- ax : `~astropy.vizualisation.WCSAxes` Axes to plot on. If no axes are given, the region is shown using the minimal equivalent WCS geometry. **kwargs : dict Keyword arguments forwarded to `~regions.PixelRegion.as_artist` Returns ------- ax : `~astropy.vizualisation.WCSAxes` Axes to plot on. """ import matplotlib.pyplot as plt from matplotlib.collections import PatchCollection from astropy.visualization.wcsaxes import WCSAxes if ax is None: ax = plt.gca() if not isinstance(ax, WCSAxes): ax.remove() wcs_geom = self.to_wcs_geom() m = Map.from_geom(wcs_geom.to_image()) fig, ax, cbar = m.plot(add_cbar=False) regions = compound_region_to_regions(self.region) artists = [ region.to_pixel(wcs=ax.wcs).as_artist() for region in regions ] kwargs.setdefault("fc", "None") patches = PatchCollection(artists, **kwargs) ax.add_collection(patches) return ax
def is_all_point_sky_regions(self): """Whether regions are all point regions""" regions = compound_region_to_regions(self.region) return np.all([isinstance(_, PointSkyRegion) for _ in regions])