Beispiel #1
0
    def make_mask_energy_aeff_max(self, dataset):
        """Make safe energy mask from effective area maximum value.

        Parameters
        ----------
        dataset : `~gammapy.datasets.MapDataset` or `~gammapy.datasets.SpectrumDataset`
            Dataset to compute mask for.

        Returns
        -------
        mask_safe : `~numpy.ndarray`
            Safe data range mask.
        """
        geom = dataset._geom

        if self.position is None:
            position = PointSkyRegion(dataset.counts.geom.center_skydir)
        else:
            position = PointSkyRegion(self.position)

        exposure = dataset.exposure.get_spectrum(position)

        energy = exposure.geom.axes["energy_true"]
        aeff = EffectiveAreaTable(
            energy_axis_true=energy,
            data=(exposure.quantity / dataset.gti.time_sum).squeeze(),
        )
        aeff_thres = (self.aeff_percent / 100) * aeff.max_area
        e_min = aeff.find_energy(aeff_thres)
        return geom.energy_mask(emin=e_min)
Beispiel #2
0
def test_get_spectrum():
    axis = MapAxis.from_bounds(1, 10, nbin=3, unit="TeV", name="energy")

    geom = WcsGeom.create(skydir=(0, 0),
                          width=(2.5, 2.5),
                          binsz=0.5,
                          axes=[axis],
                          frame="galactic")

    m = Map.from_geom(geom)
    m.data += 1

    center = SkyCoord(0, 0, frame="galactic", unit="deg")
    region = CircleSkyRegion(center=center, radius=1 * u.deg)

    spec = m.get_spectrum(region=region)
    assert_allclose(spec.data.squeeze(), [13.0, 13.0, 13.0])

    spec = m.get_spectrum(region=region, func=np.mean)
    assert_allclose(spec.data.squeeze(), [1.0, 1.0, 1.0])

    spec = m.get_spectrum()
    assert isinstance(spec.geom.region, RectangleSkyRegion)

    region = PointSkyRegion(center)
    spec = m.get_spectrum(region=region)
    assert_allclose(spec.data.squeeze(), [1.0, 1.0, 1.0])
Beispiel #3
0
    def from_regions(cls, regions, **kwargs):
        """Create region geom from list of regions

        The regions are combined with union to a compound region.

        Parameters
        ----------
        regions : list of `~regions.SkyRegion` or str
            Regions
        **kwargs: dict
            Keyword arguments forwarded to `RegionGeom`

        Returns
        -------
        geom : `RegionGeom`
            Region map geometry
        """
        if isinstance(regions, str):
            regions = Regions.parse(data=regions, format="ds9")
        elif isinstance(regions, SkyRegion):
            regions = [regions]
        elif isinstance(regions, SkyCoord):
            regions = [PointSkyRegion(center=regions)]

        if regions:
            regions = regions_to_compound_region(regions)

        return cls(region=regions, **kwargs)
Beispiel #4
0
    def to_region_nd_map(self,
                         region,
                         func=np.nansum,
                         weights=None,
                         method="nearest"):
        """Get region ND map in a given region.

        By default the whole map region is considered.

        Parameters
        ----------
        region: `~regions.Region` or `~astropy.coordinates.SkyCoord`
             Region.
        func : numpy.func
            Function to reduce the data. Default is np.nansum.
            For boolean Map, use np.any or np.all.
        weights : `WcsNDMap`
            Array to be used as weights. The geometry must be equivalent.
        method : {"nearest", "linear"}
            How to interpolate if a position is given.

        Returns
        -------
        spectrum : `~gammapy.maps.RegionNDMap`
            Spectrum in the given region.
        """
        from gammapy.maps import RegionGeom, RegionNDMap

        if isinstance(region, SkyCoord):
            region = PointSkyRegion(region)

        if weights is not None:
            if not self.geom == weights.geom:
                raise ValueError(
                    "Incompatible spatial geoms between map and weights")

        geom = RegionGeom(region=region, axes=self.geom.axes)

        if isinstance(region, PointSkyRegion):
            coords = geom.get_coord()
            data = self.interp_by_coord(coords=coords, method=method)
            if weights is not None:
                data *= weights.interp_by_coord(coords=coords, method=method)
        else:
            cutout = self.cutout(position=geom.center_skydir,
                                 width=np.max(geom.width))

            if weights is not None:
                weights_cutout = weights.cutout(position=geom.center_skydir,
                                                width=geom.width)
                cutout.data *= weights_cutout.data

            mask = cutout.geom.to_image().region_mask([region]).data
            data = func(cutout.data[..., mask], axis=-1)

        return RegionNDMap(geom=geom,
                           data=data,
                           unit=self.unit,
                           meta=self.meta.copy())
Beispiel #5
0
    def make_mask_energy_aeff_max(self, dataset, observation=None):
        """Make safe energy mask from effective area maximum value.

        Parameters
        ----------
        dataset : `~gammapy.datasets.MapDataset` or `~gammapy.datasets.SpectrumDataset`
            Dataset to compute mask for.
        observation: `~gammapy.data.Observation`
            Observation to compute mask for. It is a mandatory argument when fixed_offset is set.

        Returns
        -------
        mask_safe : `~numpy.ndarray`
            Safe data range mask.
        """
        geom = dataset._geom

        if self.fixed_offset:
            if observation:
                position = observation.pointing_radec.directional_offset_by(
                    position_angle=0.0 * u.deg, separation=self.fixed_offset)
            else:
                raise ValueError(
                    f"observation argument is mandatory with {self.fixed_offset}"
                )

        elif self.position is None and self.fixed_offset is None:
            position = PointSkyRegion(dataset._geom.center_skydir)
        else:
            position = PointSkyRegion(self.position)

        aeff = (dataset.exposure.get_spectrum(position) /
                dataset.exposure.meta["livetime"])
        model = TemplateSpectralModel.from_region_map(aeff)

        energy_true = model.energy
        energy_min = energy_true[np.where(model.values > 0)[0][0]]
        energy_max = energy_true[-1]

        aeff_thres = (self.aeff_percent / 100) * aeff.quantity.max()
        inversion = model.inverse(aeff_thres,
                                  energy_min=energy_min,
                                  energy_max=energy_max)
        if not np.isnan(inversion[0]):
            energy_min = inversion[0]
        return geom.energy_mask(energy_min=energy_min)
Beispiel #6
0
    def to_region_nd_map(self, region=None, func=np.nansum, weights=None):
        """Get region ND map in a given region.

        By default the whole map region is considered.

        Parameters
        ----------
        region: `~regions.Region` or `~astropy.coordinates.SkyCoord`
             Region.
        func : numpy.func
            Function to reduce the data. Default is np.nansum.
            For boolean Map, use np.any or np.all.
        weights : `WcsNDMap`
            Array to be used as weights. The geometry must be equivalent.

        Returns
        -------
        spectrum : `~gammapy.maps.RegionNDMap`
            Spectrum in the given region.
        """
        if isinstance(region, SkyCoord):
            region = PointSkyRegion(region)
        elif region is None:
            width, height = self.geom.width
            region = RectangleSkyRegion(center=self.geom.center_skydir,
                                        width=width[0],
                                        height=height[0])

        if weights is not None:
            if not self.geom == weights.geom:
                raise ValueError(
                    "Incompatible spatial geoms between map and weights")

        geom = RegionGeom(region=region,
                          axes=self.geom.axes,
                          wcs=self.geom.wcs)

        if isinstance(region, PointSkyRegion):
            coords = geom.get_coord()
            data = self.get_by_coord(coords=coords)
            if weights is not None:
                data *= weights.get_by_coord(coords=coords)
        else:
            cutout = self.cutout(position=geom.center_skydir, width=geom.width)

            if weights is not None:
                weights_cutout = weights.cutout(position=geom.center_skydir,
                                                width=geom.width)
                cutout.data *= weights_cutout.data

            mask = cutout.geom.to_image().region_mask([region]).data
            idx_y, idx_x = np.where(mask)
            data = func(cutout.data[..., idx_y, idx_x], axis=-1)

        return RegionNDMap(geom=geom, data=data, unit=self.unit)
Beispiel #7
0
def get_spectrumdataset_rad_max(name, e_min=0.005 * u.TeV):
    """get the spectrum dataset maker for the energy-dependent spectrum extraction"""
    target_position = SkyCoord(ra=83.63, dec=22.01, unit="deg", frame="icrs")
    on_center = PointSkyRegion(target_position)

    energy_axis = MapAxis.from_energy_bounds(
        e_min, 50, nbin=28, per_decade=False, unit="TeV", name="energy"
    )
    energy_axis_true = MapAxis.from_energy_bounds(
        e_min, 50, nbin=20, per_decade=False, unit="TeV", name="energy_true"
    )

    geom = RegionGeom.create(region=on_center, axes=[energy_axis])

    return SpectrumDataset.create(
        geom=geom, energy_axis_true=energy_axis_true, name=name
    )
Beispiel #8
0
def FindBoxSource(catalog, GorC, srcReg, freeReg, outfile):
    catalog = LoadModel(catalog)
    model = NewModel()
    for srcName in catalog.SrcList:
        skycrd_C = catalog.GetSrcDir(srcName)
        if GorC == 'C':
            xref, yref = skycrd_C
        if GorC == 'G':
            skycrd_G = maptools.skycrdC2G(skycrd_C)[0]
            xref, yref = skycrd_G
        xmin, xmax, ymin, ymax = srcReg
        if xref > xmin and xref < xmax and yref > ymin and yref < ymax:
            print(srcName, xref, yref)
            srcEle = catalog.GetSrcEle(srcName)
            if srcEle.attrib['type'] == 'PointSource':
                model.AddPointSource(srcName)
            if srcEle.attrib['type'] == 'DiffuseSource':
                spatialFile = srcEle.find('spatialModel').attrib['file']
                model.AddDiffuseSource(srcName, SpatialFile=spatialFile)
            model.AddSrcEle(srcName, srcEle)
    model.SaveModel(outfile)

    regionList = []
    model = LoadModel(outfile)
    for srcName in model.SrcList:
        skycrd_C = catalog.GetSrcDir(srcName)
        center = SkyCoord(*skycrd_C, unit='deg')
        region = PointSkyRegion(center)
        regionList.append(region)

        if GorC == 'C':
            xref, yref = skycrd_C
        if GorC == 'G':
            skycrd_G = maptools.skycrdC2G(skycrd_C)[0]
            xref, yref = skycrd_G
        xmin, xmax, ymin, ymax = freeReg
        if xref < xmin or xref > xmax or yref < ymin or yref > ymax:
            print(srcName, xref, yref)
            for parName in model.FreeParDict[srcName]:
                print(parName)
                model.SetParFree(srcName, parName, 0)
    model.SaveModel(outfile)

    regfile = outfile.split('.')[0] + '.reg'
    write_ds9(regionList, regfile)
Beispiel #9
0
    def to_region_nd_map(self, region=None, func=np.nansum):
        """Get region ND map in a given region.

        By default the whole map region is considered.

        Parameters
        ----------
        region: `~regions.Region` or `~astropy.coordinates.SkyCoord`
             Region.
        func : numpy.ufunc
            Function to reduce the data.

        Returns
        -------
        spectrum : `~gammapy.maps.RegionNDMap`
            Spectrum in the given region.
        """
        if isinstance(region, SkyCoord):
            region = PointSkyRegion(region)
        elif region is None:
            width, height = self.geom.width
            region = RectangleSkyRegion(
                center=self.geom.center_skydir, width=width[0], height=height[0]
            )

        geom = RegionGeom(
            region=region,
            axes=self.geom.axes,
            wcs=self.geom.wcs
        )

        if isinstance(region, PointSkyRegion):
            coords = geom.get_coord()
            data = self.get_by_coord(coords=coords)
        else:
            cutout = self.cutout(position=geom.center_skydir, width=geom.width)
            mask = cutout.geom.to_image().region_mask([region])
            idx_y, idx_x = np.where(mask)
            data = func(cutout.data[..., idx_y, idx_x], axis=-1)

        return RegionNDMap(geom=geom, data=data, unit=self.unit)
Beispiel #10
0
    def test_regions_sky_has_wcs(self):
        # Mimic interactive region (before)
        self.imviz._apply_interactive_region('bqplot:circle', (1.5, 2.5),
                                             (3.6, 4.6))

        sky = SkyCoord(ra=337.5202808, dec=-20.833333059999998, unit='deg')
        my_reg_sky = CircleSkyRegion(sky, Angle(0.5, u.arcsec))
        bad_regions = self.imviz.load_static_regions(
            {'my_reg_sky_1': my_reg_sky})
        assert len(bad_regions) == 0

        # Unsupported shape but a valid region
        my_pt_reg_sky = PointSkyRegion(center=sky)
        with pytest.warns(UserWarning, match='failed to load, skipping'):
            bad_regions = self.imviz.load_static_regions(
                {'my_pt_reg_sky_1': my_pt_reg_sky})
        assert len(bad_regions) == 1

        # Mimic interactive regions (after)
        self.imviz._apply_interactive_region('bqplot:ellipse', (-2, 0),
                                             (5, 4.5))
        self.imviz._apply_interactive_region('bqplot:rectangle', (0, 0),
                                             (10, 10))

        # Check interactive regions. We do not check if the translation is correct,
        # that check hopefully is already done in glue-astronomy.
        # Apparently, static region ate up one number...
        subsets = self.imviz.get_interactive_regions()
        assert list(subsets.keys()) == ['Subset 1', 'Subset 3',
                                        'Subset 4'], subsets
        assert isinstance(subsets['Subset 1'], CirclePixelRegion)
        assert isinstance(subsets['Subset 3'], EllipsePixelRegion)
        assert isinstance(subsets['Subset 4'], RectanglePixelRegion)

        # Check static region
        self.verify_region_loaded('my_reg_sky_1')
        self.verify_region_loaded('my_pt_reg_sky_1', count=0)
Beispiel #11
0
def test_make_psf(pars, data_store):
    energy_axis = pars["energy"]
    rad_axis = pars["rad"]

    psf = data_store.obs(23523).psf

    if energy_axis is None:
        energy_axis = psf.energy_axis

    if rad_axis is None:
        rad_axis = psf.rad_axis

    geom = RegionGeom(
        region=PointSkyRegion(SkyCoord(83.63, 22.01, unit="deg")),
        axes=[rad_axis, energy_axis]
    )

    maker = MapDatasetMaker()

    psf_map = maker.make_psf(geom=geom, observation=data_store.obs(23523))
    psf = psf_map.get_energy_dependent_table_psf()

    assert psf.energy.unit == "GeV"
    assert psf.energy.shape == pars["energy_shape"]
    assert_allclose(psf.energy.value[15], pars["psf_energy"], rtol=1e-3)

    assert psf.rad.unit == "rad"
    assert psf.rad.shape == pars["rad_shape"]
    assert_allclose(psf.rad.value[15], pars["psf_rad"], rtol=1e-3)

    assert psf.exposure.unit == "cm2 s"
    assert psf.exposure.shape == pars["energy_shape"]
    assert_allclose(psf.exposure.value[15], pars["psf_exposure"], rtol=1e-3)

    assert psf.psf_value.unit == "sr-1"
    assert psf.psf_value.shape == pars["psf_value_shape"]
    assert_allclose(psf.psf_value.value[15, 50], pars["psf_value"], rtol=1e-3)
Beispiel #12
0
def FindCircleSource(catalog, skycrd0_C, srcRad, freeRad, outfile):
    catalog = LoadModel(catalog)

    model = NewModel()
    for srcName in catalog.SrcList:
        skycrd_C = catalog.GetSrcDir(srcName)
        rad = maptools.Sep(skycrd_C, skycrd0_C)
        if rad < srcRad:
            print(srcName, rad)
            srcEle = catalog.GetSrcEle(srcName)
            if srcEle.attrib['type'] == 'PointSource':
                model.AddPointSource(srcName)
            if srcEle.attrib['type'] == 'DiffuseSource':
                spatialFile = srcEle.find('spatialModel').attrib['file']
                model.AddDiffuseSource(srcName, SpatialFile=spatialFile)
            model.AddSrcEle(srcName, srcEle)
    model.SaveModel(outfile)

    regionList = []
    model = LoadModel(outfile)
    for srcName in model.SrcList:
        skycrd_C = catalog.GetSrcDir(srcName)
        center = SkyCoord(*skycrd_C, unit='deg')
        region = PointSkyRegion(center)
        regionList.append(region)

        rad = maptools.Sep(skycrd_C, skycrd0_C)
        if rad > freeRad:
            print(srcName, rad)
            for parName in model.FreeParDict[srcName]:
                print(parName)
                model.SetParFree(srcName, parName, 0)
    model.SaveModel(outfile)

    regfile = outfile.split('.')[0] + '.reg'
    write_ds9(regionList, regfile)
Beispiel #13
0
 def to_region(self, **kwargs):
     """Model outline (`~regions.PointSkyRegion`)."""
     return PointSkyRegion(center=self.position, **kwargs)