Example #1
0
    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)
Example #2
0
 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()
Example #3
0
    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)
Example #4
0
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
Example #5
0
    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