def region_mask(self, regions, inside=True): """Create a mask from a given list of regions The mask is filled such that a pixel inside the region is filled with "True". To invert the mask, e.g. to create a mask with exclusion regions the tilde (~) operator can be used (see example below). Parameters ---------- regions : str, `~regions.Region` or list of `~regions.Region` Region or list of regions (pixel or sky regions accepted). A region can be defined as a string ind DS9 format as well. See http://ds9.si.edu/doc/ref/region.html for details. inside : bool For ``inside=True``, pixels in the region to True (the default). For ``inside=False``, pixels in the region are False. Returns ------- mask_map : `~gammapy.maps.WcsNDMap` of boolean type Boolean region mask Examples -------- Make an exclusion mask for a circular region:: from regions import CircleSkyRegion from astropy.coordinates import SkyCoord, Angle from gammapy.maps import WcsNDMap, WcsGeom pos = SkyCoord(0, 0, unit='deg') geom = WcsGeom.create(skydir=pos, npix=100, binsz=0.1) region = CircleSkyRegion( SkyCoord(3, 2, unit='deg'), Angle(1, 'deg'), ) # the Gammapy convention for exclusion regions is to take the inverse mask = ~geom.region_mask([region]) Note how we made a list with a single region, since this method expects a list of regions. """ from gammapy.maps import Map, RegionGeom if not self.is_regular: raise ValueError("Multi-resolution maps not supported yet") geom = RegionGeom.from_regions(regions, wcs=self.wcs) idx = self.get_idx() mask = geom.contains_wcs_pix(idx) if not inside: np.logical_not(mask, out=mask) return Map.from_geom(self, data=mask)
def _get_components_geom(models): energy_axis = MapAxis.from_energy_bounds( "100 GeV", "100 TeV", nbin=10, per_decade=True, name="energy_true" ) regions = [m.spatial_model.evaluation_region for m in models] geom = RegionGeom.from_regions( regions, binsz_wcs="0.02 deg", axes=[energy_axis] ) return geom.to_wcs_geom()
def select_region(self, regions, wcs=None): """Select events in given region. Parameters ---------- regions : str, `~regions.Region` or list of `~regions.Region` Region or list of regions (pixel or sky regions accepted). A region can be defined as a string ind DS9 format as well. See http://ds9.si.edu/doc/ref/region.html for details. wcs : `~astropy.wcs.WCS` World coordinate system transformation Returns ------- event_list : `EventList` Copy of event list with selection applied. """ geom = RegionGeom.from_regions(regions, wcs=wcs) mask = geom.contains(self.radec) return self.select_row_subset(mask)
def make_counts_off_rad_max( geom, rad_max, events, binsz, exclusion_mask, min_distance, min_distance_input, max_region_number, angle_increment, ): """Extract the OFF counts and the ON / OFF acceptance considering for the sizes of the ON and OFF regions the values in the `RAD_MAX_2D` table. Per each estimated energy bin a `ReflectedRegionsFinder` is defined to search for the OFF regions. Parameters ---------- geom : `~gammapy.maps.RegionGeom` reference map geom 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 binsz : `~astropy.coordinates.Angle` Bin size of the reference map used for region finding. exclusion_mask : `~gammapy.maps.WcsNDMap`, optional Exclusion mask min_distance : `~astropy.coordinates.Angle`, optional Minimal distance between two consecutive reflected regions min_distance_input : `~astropy.coordinates.Angle`, optional Minimal distance from input region max_region_number : int, optional Maximum number of regions to use angle_increment : `~astropy.coordinates.Angle`, optional Rotation angle applied when a region falls in an excluded region Returns ------- counts_off : `~gammapy.maps.RegionNDMap` OFF Counts vs estimated energy extracted from the ON region. acceptance_off : `~gammapy.maps.RegionNDMap` ratio of the acceptances of the OFF to ON regions. """ from .background import ReflectedRegionsFinder rad_max = get_rad_max_vs_energy(rad_max, events.pointing_radec, geom) counts_off_list = [] acceptance_off_list = [] # we have to define an ON region and a region finder for each energy bin for i, rad in enumerate(rad_max): on_region = CircleSkyRegion(center=geom.center_skydir, radius=rad) energy_range = geom.axes["energy"].slice(i) finder = ReflectedRegionsFinder( binsz=binsz, exclusion_mask=exclusion_mask, center=events.pointing_radec, region=on_region, min_distance=min_distance, min_distance_input=min_distance_input, max_region_number=max_region_number, angle_increment=angle_increment, ) regions = finder.run() if len(regions) > 0: off_region_geom = RegionGeom.from_regions(regions=regions, axes=[energy_range], wcs=finder.geom_ref.wcs) counts_off = RegionNDMap.from_geom(geom=off_region_geom) counts_off.fill_events(events) counts_off_list.append(counts_off.data[0]) else: log.warning( f"ReflectedRegionsBackgroundMaker failed in estimated energy bin {i}." ) counts_off_list.append([[0]]) acceptance_off_list.append(len(regions)) # create the final arrays with the OFF counts and the acceptance counts_off = RegionNDMap.from_geom(geom=geom, data=np.asarray(counts_off_list)) acceptance_off = RegionNDMap.from_geom( geom=geom, data=np.asarray(acceptance_off_list)) return counts_off, acceptance_off
def make_counts_off(self, dataset, observation): """Make off counts. **NOTE for 1D analysis:** as for `~gammapy.makers.map.MapDatasetMaker.make_counts`, if the geometry of the dataset is a `~regions.CircleSkyRegion` then only a single instance of the `ReflectedRegionsFinder` will be called. If, on the other hand, the geometry of the dataset is a `~regions.PointSkyRegion`, then we have to call the `ReflectedRegionsFinder` several time, each time with a different size of the on region that we will read from the `RAD_MAX_2D` table. Parameters ---------- dataset : `~gammapy.datasets.SpectrumDataset` Spectrum dataset. observation : `~gammapy.observation.Observation` Observation container. Returns ------- counts_off : `~gammapy.maps.RegionNDMap` Counts vs estimated energy extracted from the OFF regions. """ geom = dataset.counts.geom energy_axis = geom.axes["energy"] events = observation.events is_point_like = observation.rad_max is not None if is_point_like and not geom.is_all_point_sky_regions: raise ValueError( "Must use PointSkyRegion on region in point-like analysis," f" got {type(geom.region)} instead") regions_off, wcs = self.region_finder.run( center=observation.pointing_radec, region=geom.region, exclusion_mask=self.exclusion_mask, ) if is_point_like and len(regions_off) > 0: regions_off = self._filter_regions_off_rad_max( regions_off, energy_axis, geom, events, observation.rad_max) if len(regions_off) == 0: log.warning( "ReflectedRegionsBackgroundMaker failed. No OFF region found " f"outside exclusion mask for dataset '{dataset.name}'.") return None, RegionNDMap.from_geom(geom=geom, data=0) geom_off = RegionGeom.from_regions( regions=regions_off, axes=[energy_axis], wcs=wcs, ) if is_point_like: counts_off = make_counts_off_rad_max( geom_off=geom_off, rad_max=observation.rad_max, events=events, ) else: counts_off = RegionNDMap.from_geom(geom=geom_off) counts_off.fill_events(events) acceptance_off = RegionNDMap.from_geom(geom=geom_off, data=len(regions_off)) return counts_off, acceptance_off