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)
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])
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)
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())
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)
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)
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 )
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)
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)
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)
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)
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)
def to_region(self, **kwargs): """Model outline (`~regions.PointSkyRegion`).""" return PointSkyRegion(center=self.position, **kwargs)