def partial_wcs_flux_map(): energy_axis = MapAxis.from_energy_bounds(0.1, 10, 2, unit='TeV') map_dict = {} map_dict["norm"] = WcsNDMap.create(npix=10, frame='galactic', axes=[energy_axis], unit='') map_dict["norm"].data += 1.0 map_dict["norm_err"] = WcsNDMap.create(npix=10, frame='galactic', axes=[energy_axis], unit='') map_dict["norm_err"].data += 0.1 # Add another map map_dict["sqrt_ts"] = WcsNDMap.create(npix=10, frame='galactic', axes=[energy_axis], unit='') map_dict["sqrt_ts"].data += 1.0 return map_dict
def test_asmooth_map_dataset_on_off(): kernel = Tophat2DKernel scales = ASmoothMapEstimator.get_scales(3, factor=2, kernel=kernel) * 0.1 * u.deg asmooth = ASmoothMapEstimator(kernel=kernel, scales=scales, method="lima", threshold=2.5) counts = WcsNDMap.create(npix=(50, 50), binsz=0.02, unit="") counts += 2 counts_off = WcsNDMap.create(npix=(50, 50), binsz=0.02, unit="") counts_off += 3 acceptance = WcsNDMap.create(npix=(50, 50), binsz=0.02, unit="") acceptance += 1 acceptance_off = WcsNDMap.create(npix=(50, 50), binsz=0.02, unit="") acceptance_off += 3 dataset = MapDatasetOnOff( counts=counts, counts_off=counts_off, acceptance=acceptance, acceptance_off=acceptance_off, ) smoothed = asmooth.run(dataset) assert_allclose(smoothed["counts"].data[25, 25], 2) assert_allclose(smoothed["background"].data[25, 25], 1) assert_allclose(smoothed["significance"].data[25, 25], 4.391334)
def test_get_by_coord_bool_int(): mask = WcsNDMap.create(width=2, dtype="bool") coords = {"lon": [0, 3], "lat": [0, 3]} vals = mask.get_by_coord(coords) assert_allclose(vals, [0, np.nan]) mask = WcsNDMap.create(width=2, dtype="int") coords = {"lon": [0, 3], "lat": [0, 3]} vals = mask.get_by_coord(coords) assert_allclose(vals, [0, np.nan])
def test_stack_unit_handling(): m = WcsNDMap.create(npix=(3, 3), unit="m2 s") m.data += 1 m_other = WcsNDMap.create(npix=(3, 3), unit="cm2 s") m_other.data += 1 m.stack(m_other) assert_allclose(m.data, 1.0001)
def setup(self): self.images = {} self.images["counts"] = WcsNDMap.create(binsz=0.02, npix=101, dtype=float) self.images["counts"].data += 1.0 self.images["background"] = WcsNDMap.create(binsz=0.02, npix=101, dtype=float) self.images["background"].data += 1e10 exclusion = WcsNDMap.create(binsz=0.02, npix=101, dtype=float) exclusion.data += 1 exclusion.data[40:60, 40:60] = 0 self.images["exclusion"] = exclusion
def wcs_flux_map(): energy_axis = MapAxis.from_energy_bounds(0.1, 10, 2, unit="TeV") map_dict = {} map_dict["norm"] = WcsNDMap.create(npix=10, frame="galactic", axes=[energy_axis], unit="") map_dict["norm"].data += 1.0 map_dict["norm_err"] = WcsNDMap.create(npix=10, frame="galactic", axes=[energy_axis], unit="") map_dict["norm_err"].data += 0.1 map_dict["norm_errp"] = WcsNDMap.create(npix=10, frame="galactic", axes=[energy_axis], unit="") map_dict["norm_errp"].data += 0.2 map_dict["norm_errn"] = WcsNDMap.create(npix=10, frame="galactic", axes=[energy_axis], unit="") map_dict["norm_errn"].data += 0.2 map_dict["norm_ul"] = WcsNDMap.create(npix=10, frame="galactic", axes=[energy_axis], unit="") map_dict["norm_ul"].data += 2.0 # Add another map map_dict["sqrt_ts"] = WcsNDMap.create(npix=10, frame="galactic", axes=[energy_axis], unit="") map_dict["sqrt_ts"].data += 1.0 # Add another map map_dict["ts"] = WcsNDMap.create(npix=10, frame="galactic", axes=[energy_axis], unit="") map_dict["ts"].data[1] += 3.0 # Add another map map_dict["success"] = WcsNDMap.create(npix=10, frame="galactic", axes=[energy_axis], unit="", dtype=np.dtype(bool)) map_dict["success"].data = True map_dict["success"].data[0, 0, 1] = False return map_dict
def plot_image(self): """Quick look counts map sky plot.""" from gammapy.maps import WcsNDMap m = WcsNDMap.create(npix=(360, 180), binsz=1.0, proj="AIT", frame="galactic") m.fill_by_coord(self.radec) m.plot(stretch="sqrt")
def test_flux_estimator_norm_range_template(): energy = MapAxis.from_energy_bounds(0.1, 10, 3.0, unit="TeV", name="energy_true") template = WcsNDMap.create(npix=10, axes=[energy], unit="cm-2 s-1 sr-1 TeV-1") spatial = TemplateSpatialModel(template, normalize=False) spectral = PowerLawNormSpectralModel() model = SkyModel(spectral_model=spectral, spatial_model=spatial, name="test") model.spectral_model.norm.max = 10 model.spectral_model.norm.min = 0 estimator = FluxEstimator(source="test", selection_optional=[], reoptimize=True) scale_model = estimator.get_scale_model(Models([model])) assert_allclose(scale_model.norm.min, 0) assert_allclose(scale_model.norm.max, 10) assert scale_model.norm.interp == "log"
def test_convolve_pixel_scale_error(): m = WcsNDMap.create(binsz=0.05 * u.deg, width=5 * u.deg) kgeom = WcsGeom.create(binsz=0.04 * u.deg, width=0.5 * u.deg) kernel = PSFKernel.from_gauss(kgeom, sigma=0.1 * u.deg, max_radius=1.5 * u.deg) with pytest.raises(ValueError): m.convolve(kernel)
def test_asmooth_map_dataset_on_off(): kernel = Tophat2DKernel scales = ASmoothMapEstimator.get_scales(3, factor=2, kernel=kernel) * 0.1 * u.deg asmooth = ASmoothMapEstimator(kernel=kernel, scales=scales, method="lima", threshold=2.5) axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=1) counts = WcsNDMap.create(npix=(50, 50), binsz=0.02, unit="", axes=[axis]) counts += 2 counts_off = WcsNDMap.create(npix=(50, 50), binsz=0.02, unit="", axes=[axis]) counts_off += 3 acceptance = WcsNDMap.create(npix=(50, 50), binsz=0.02, unit="", axes=[axis]) acceptance += 1 acceptance_off = WcsNDMap.create(npix=(50, 50), binsz=0.02, unit="", axes=[axis]) acceptance_off += 3 dataset = MapDatasetOnOff( counts=counts, counts_off=counts_off, acceptance=acceptance, acceptance_off=acceptance_off, ) smoothed = asmooth.run(dataset) assert_allclose(smoothed["counts"].data[25, 25], 2) assert_allclose(smoothed["background"].data[25, 25], 1.25) assert_allclose(smoothed["significance"].data[25, 25], 3.079799117645, rtol=1e-2)
def test_map_interp_one_bin(): m = WcsNDMap.create(npix=(2, 1)) m.data = np.array([[1, 2]]) coords = {"lon": 0, "lat": [0, 0]} data = m.interp_by_coord(coords) assert data.shape == (2, ) assert_allclose(data, 1.5)
def test_wcs_nd_map_pad_axis(): axis = MapAxis.from_nodes([0, 1], unit="deg", name="axis") m = WcsNDMap.create(npix=3, axes=[axis]) m.data += np.array([1, 2]).reshape((-1, 1, 1)) m_pad = m.pad(axis_name="axis", pad_width=1, mode="edge") m_pad.data assert_allclose(m_pad.data[:, 1, 1], [1, 1, 2, 2])
def test_convolve_pixel_scale_error(): m = WcsNDMap.create(binsz=0.05 * u.deg, width=5 * u.deg) kgeom = WcsGeom.create(binsz=0.04 * u.deg, width=0.5 * u.deg) kernel = PSFKernel.from_gauss(kgeom, sigma=0.1 * u.deg, max_radius=1.5 * u.deg) with pytest.raises(ValueError) as excinfo: m.convolve(kernel) assert "Pixel size of kernel and map not compatible." == str(excinfo.value)
def test_map_spectrum_weight(): axis = MapAxis.from_edges([0.1, 10, 1000], unit="TeV", name="energy") expo_map = WcsNDMap.create(npix=10, binsz=1, axes=[axis], unit="m2 s") expo_map.data += 1 spectrum = ConstantSpectralModel(const="42 cm-2 s-1 TeV-1") weighted_expo = _map_spectrum_weight(expo_map, spectrum) assert weighted_expo.data.shape == (2, 10, 10) assert weighted_expo.unit == "m2 s" assert_allclose(weighted_expo.data.sum(), 100)
def test_convolve_kernel_size_error(): axis_1 = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=2) axis_2 = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=3) m = WcsNDMap.create(binsz=0.05 * u.deg, width=5 * u.deg, axes=[axis_1]) kgeom = WcsGeom.create(binsz=0.05 * u.deg, width=0.5 * u.deg, axes=[axis_2]) kernel = PSFKernel.from_gauss(kgeom, sigma=0.1 * u.deg, max_radius=1.5 * u.deg) with pytest.raises(ValueError): m.convolve(kernel)
def _counts_image(self): opts = { "width": (7, 7), "binsz": 0.1, "proj": "TAN", "frame": "galactic", "skydir": self.pointing_radec, } m = WcsNDMap.create(**opts) m.fill_by_coord(self.radec) m = m.smooth(width=1) return m
def _scan_position(self, name, **kwargs): saved_state = LikelihoodState(self.like) skydir = kwargs.pop('skydir', self.roi[name].skydir) scan_cdelt = kwargs.pop('scan_cdelt', 0.02) nstep = kwargs.pop('nstep', 5) use_cache = kwargs.get('use_cache', True) use_pylike = kwargs.get('use_pylike', False) optimizer = kwargs.get('optimizer', {}) # Fit without source self.zero_source(name, loglevel=logging.DEBUG) fit_output_nosrc = self._fit(loglevel=logging.DEBUG, **optimizer) self.unzero_source(name, loglevel=logging.DEBUG) saved_state.restore() self.free_norm(name, loglevel=logging.DEBUG) lnlmap = WcsNDMap.create(skydir=skydir, binsz=scan_cdelt, npix=(nstep, nstep), frame=wcs_utils.coordsys_to_frame( wcs_utils.get_coordsys(self.geom.wcs))) src = self.roi.copy_source(name) if use_cache and not use_pylike: self._create_srcmap_cache(src.name, src) coord = MapCoord.create(lnlmap.geom.get_coord(flat=True), frame=lnlmap.geom.frame) scan_skydir = coord.skycoord.icrs for lon, lat, ra, dec in zip(coord.lon, coord.lat, scan_skydir.ra.deg, scan_skydir.dec.deg): spatial_pars = {'ra': ra, 'dec': dec} self.set_source_morphology(name, spatial_pars=spatial_pars, use_pylike=use_pylike) fit_output = self._fit(loglevel=logging.DEBUG, **optimizer) lnlmap.set_by_coord((lon, lat), fit_output['loglike']) self.set_source_morphology(name, spatial_pars=src.spatial_pars, use_pylike=use_pylike) saved_state.restore() lnlmap.data -= fit_output_nosrc['loglike'] tsmap = WcsNDMap(lnlmap.geom, 2.0 * lnlmap.data) self._clear_srcmap_cache() return tsmap, fit_output_nosrc['loglike']
def _counts_image(self): width = self.galactic.b.max().deg - self.galactic.b.min().deg opts = { "width": (width, width), "binsz": 0.05, "proj": "TAN", "frame": "galactic", "skydir": self.pointing_radec, } m = WcsNDMap.create(**opts) m.fill_by_coord(self.radec) m = m.smooth(width=0.5) return m
def map_flux_estimate(): axis = MapAxis.from_energy_edges((0.1, 1.0, 10.0), unit="TeV") nmap = WcsNDMap.create(npix=5, axes=[axis]) cols = dict() cols["norm"] = nmap.copy(data=1.0) cols["norm_err"] = nmap.copy(data=0.1) cols["norm_errn"] = nmap.copy(data=0.2) cols["norm_errp"] = nmap.copy(data=0.15) cols["norm_ul"] = nmap.copy(data=2.0) return cols
def _scan_position(self, name, **kwargs): saved_state = LikelihoodState(self.like) skydir = kwargs.pop('skydir', self.roi[name].skydir) scan_cdelt = kwargs.pop('scan_cdelt', 0.02) nstep = kwargs.pop('nstep', 5) use_cache = kwargs.get('use_cache', True) use_pylike = kwargs.get('use_pylike', False) optimizer = kwargs.get('optimizer', {}) # Fit without source self.zero_source(name, loglevel=logging.DEBUG) fit_output_nosrc = self._fit(loglevel=logging.DEBUG, **optimizer) self.unzero_source(name, loglevel=logging.DEBUG) saved_state.restore() self.free_norm(name, loglevel=logging.DEBUG) lnlmap = WcsNDMap.create(skydir=skydir, binsz=scan_cdelt, npix=(nstep, nstep), coordsys=wcs_utils.get_coordsys(self.geom.wcs)) src = self.roi.copy_source(name) if use_cache and not use_pylike: self._create_srcmap_cache(src.name, src) coord = MapCoord.create(lnlmap.geom.get_coord(flat=True), coordsys=lnlmap.geom.coordsys) scan_skydir = coord.skycoord.icrs for lon, lat, ra, dec in zip(coord.lon, coord.lat, scan_skydir.ra.deg, scan_skydir.dec.deg): spatial_pars = {'ra': ra, 'dec': dec} self.set_source_morphology(name, spatial_pars=spatial_pars, use_pylike=use_pylike) fit_output = self._fit(loglevel=logging.DEBUG, **optimizer) lnlmap.set_by_coord((lon, lat), fit_output['loglike']) self.set_source_morphology(name, spatial_pars=src.spatial_pars, use_pylike=use_pylike) saved_state.restore() lnlmap.data -= fit_output_nosrc['loglike'] tsmap = WcsNDMap(lnlmap.geom, 2.0 * lnlmap.data) self._clear_srcmap_cache() return tsmap, fit_output_nosrc['loglike']
def _counts_image(self): from gammapy.maps import WcsNDMap opts = { "width": (7, 7), "binsz": 0.1, "proj": "TAN", "coordsys": "GAL", "skydir": self.pointing_radec, } m = WcsNDMap.create(**opts) m.fill_by_coord(self.radec) m = m.smooth(width=1) return m
def make_reference_map(region, center, binsz="0.01 deg", min_width="0.3 deg"): """Create empty reference map. The size of the map is chosen such that all reflected regions are contained on the image. To do so, the reference map width is taken to be 4 times the distance between the target region center and the rotation point. This distance is larger than the typical dimension of the region itself (otherwise the rotation point would lie inside the region). A minimal width value is added by default in case the region center and the rotation center are too close. The WCS of the map is the TAN projection at the `center` in the coordinate system used by the `region` center. Parameters ---------- region : `~regions.SkyRegion` Region to rotate center : `~astropy.coordinates.SkyCoord` Rotation point binsz : `~astropy.coordinates.Angle` Reference map bin size. Default : 0.01 deg min_width : `~astropy.coordinates.Angle` Minimal map width. Default : 0.3 deg Returns ------- reference_map : `~gammapy.maps.WcsNDMap` Map containing the region """ try: if "ra" in region.center.representation_component_names: coordsys = "CEL" else: coordsys = "GAL" except: raise TypeError("Algorithm not yet adapted to this Region shape") # width is the full width of an image (not the radius) width = 4 * region.center.separation(center) + Angle(min_width) return WcsNDMap.create(skydir=center, binsz=binsz, width=width, coordsys=coordsys, proj="TAN")
def test_convolve_vs_smooth(): axes = [ MapAxis(np.logspace(0.0, 3.0, 3), interp="log"), MapAxis(np.logspace(1.0, 3.0, 4), interp="lin"), ] binsz = 0.05 * u.deg m = WcsNDMap.create(binsz=binsz, width=1.05 * u.deg, axes=axes) m.data[:, :, 10, 10] = 1.0 desired = m.smooth(kernel="gauss", width=0.5 * u.deg, mode="constant") gauss = Gaussian2DKernel(10).array actual = m.convolve(kernel=gauss) assert_allclose(actual.data, desired.data, rtol=1e-3)
def make_reference_map(region, center, binsz="0.01 deg", min_width="0.3 deg"): """Create empty reference map. The size of the map is chosen such that all reflected regions are contained on the image. To do so, the reference map width is taken to be 4 times the distance between the target region center and the rotation point. This distance is larger than the typical dimension of the region itself (otherwise the rotation point would lie inside the region). A minimal width value is added by default in case the region center and the rotation center are too close. The WCS of the map is the TAN projection at the `center` in the coordinate system used by the `region` center. Parameters ---------- region : `~regions.SkyRegion` Region to rotate center : `~astropy.coordinates.SkyCoord` Rotation point binsz : `~astropy.coordinates.Angle` Reference map bin size. min_width : `~astropy.coordinates.Angle` Minimal map width. Returns ------- reference_map : `~gammapy.maps.WcsNDMap` Map containing the region """ frame = region.center.frame.name # width is the full width of an image (not the radius) width = 4 * region.center.separation(center) + Angle(min_width) return WcsNDMap.create(skydir=center, binsz=binsz, width=width, frame=frame, proj="TAN")
def images(): fov = 2.5 * u.deg m_ref = WcsNDMap.create(binsz=0.05, npix=201, dtype=float) m_ref.data += 1.0 coords = m_ref.geom.get_coord().skycoord center = m_ref.geom.center_skydir mask = coords.separation(center) < fov images = dict() images["counts"] = m_ref.copy(data=np.zeros_like(m_ref.data) + 2.0) images["counts"].data *= mask images["background"] = m_ref.copy(data=np.zeros_like(m_ref.data) + 1.0) images["background"].data *= mask exclusion = m_ref.copy(data=np.zeros_like(m_ref.data) + 1.0) exclusion.data[90:110, 90:110] = 0 images["exclusion"] = exclusion return images
def _counts_image(self, allsky): if allsky: opts = { "npix": (360, 180), "binsz": 1.0, "proj": "AIT", "frame": "galactic" } else: opts = { "width": self._plot_width, "binsz": 0.05, "proj": "TAN", "frame": "galactic", "skydir": self._plot_center, } m = WcsNDMap.create(**opts) m.fill_by_coord(self.radec) m = m.smooth(width=0.5) return m
"""Example how to compute and plot reflected regions.""" import matplotlib.pyplot as plt import numpy as np from astropy.coordinates import SkyCoord, Angle from regions import CircleSkyRegion from gammapy.maps import WcsNDMap from gammapy.background import ReflectedRegionsFinder # Exclude a rectangular region exclusion_mask = WcsNDMap.create(npix=(801, 701), binsz=0.01, skydir=(83.6, 23.0)) coords = exclusion_mask.geom.get_coord().skycoord mask = (Angle("23d") < coords.dec) & (coords.dec < Angle("24d")) exclusion_mask.data = np.invert(mask) pos = SkyCoord(83.633, 22.014, unit="deg") radius = Angle(0.3, "deg") on_region = CircleSkyRegion(pos, radius) center = SkyCoord(83.633, 24, unit="deg") # One can impose a minimal distance between ON region and first reflected regions finder = ReflectedRegionsFinder( region=on_region, center=center, exclusion_mask=exclusion_mask, min_distance_input="0.2 rad", ) finder.run() fig1 = plt.figure(1) finder.plot(fig=fig1)
import matplotlib.pyplot as plt from astropy.coordinates import Angle, SkyCoord from regions import CircleSkyRegion from gammapy.makers import ReflectedRegionsFinder from gammapy.maps import WcsNDMap, RegionGeom # Exclude a rectangular region exclusion_mask = WcsNDMap.create(npix=(801, 701), binsz=0.01, skydir=(83.6, 23.0)) coords = exclusion_mask.geom.get_coord().skycoord data = (Angle("23 deg") < coords.dec) & (coords.dec < Angle("24 deg")) exclusion_mask.data = ~data pos = SkyCoord(83.633, 22.014, unit="deg") radius = Angle(0.3, "deg") on_region = CircleSkyRegion(pos, radius) center = SkyCoord(83.633, 24, unit="deg") # One can impose a minimal distance between ON region and first reflected regions finder = ReflectedRegionsFinder( region=on_region, center=center, exclusion_mask=exclusion_mask, min_distance_input="0.2 rad", ) regions = finder.run() fig, axes = plt.subplots( ncols=3,
def test_plot_allsky(): m = WcsNDMap.create(binsz=10 * u.deg) with mpl_plot_check(): m.plot()
def test_plot_grid(): axis = MapAxis([0, 1, 2], node_type="edges") m = WcsNDMap.create(binsz=0.1 * u.deg, width=1 * u.deg, axes=[axis]) with mpl_plot_check(): m.plot_grid()
on_ellipse_annulus = EllipseAnnulusSkyRegion( center=position, inner_width=1.5 * u.deg, outer_width=2.5 * u.deg, inner_height=3 * u.deg, outer_height=4 * u.deg, angle=130 * u.deg, ) another_position = SkyCoord(80.3, 22.0, unit="deg") on_rectangle = RectangleSkyRegion(center=another_position, width=2.0 * u.deg, height=4.0 * u.deg, angle=50 * u.deg) # Now we plot those regions. We first create an empty map empty_map = WcsNDMap.create(skydir=position, width=10 * u.deg, binsz=0.1 * u.deg, proj="TAN") empty_map.data += 1.0 empty_map.plot(cmap="gray", vmin=0, vmax=1) # To plot the regions, we convert them to PixelRegion with the map wcs on_circle.to_pixel(empty_map.geom.wcs).plot() on_rectangle.to_pixel(empty_map.geom.wcs).plot() on_ellipse_annulus.to_pixel(empty_map.geom.wcs).plot() plt.show()
def test_plot_allsky(): axis = MapAxis([0, 1], node_type="edges") m = WcsNDMap.create(binsz=10 * u.deg, axes=[axis]) with mpl_plot_check(): m.plot()