def _make_wcsgeom_from_config(config): """Build a `WCS.Geom` object from a fermipy coniguration file""" binning = config['binning'] binsz = binning['binsz'] coordsys = binning.get('coordsys', 'GAL') roiwidth = binning['roiwidth'] proj = binning.get('proj', 'AIT') ra = config['selection']['ra'] dec = config['selection']['dec'] npix = int(np.round(roiwidth / binsz)) skydir = SkyCoord(ra * u.deg, dec * u.deg) wcsgeom = WcsGeom.create(npix=npix, binsz=binsz, proj=proj, coordsys=coordsys, skydir=skydir) return wcsgeom
def plot(self, fig=None, ax=None, cmap=None, idx=None, add_legend=False): """Standard debug plot. Parameters ---------- fig : `~matplotlib.figure.Figure` Top level container of the figure ax : `~matplotlib.axes.Axes` Axes of the figure cmap : `~matplotlib.colors.ListedColormap`, optional Color map to use idx : int, optional Observations to include in the plot, default: all add_legend : boolean, optional Enable/disable legend in the plot, default: False """ import matplotlib.pyplot as plt if "ra" in self.on_region.center.representation_component_names: coordsys = "CEL" else: coordsys = "GAL" pnt_radec = SkyCoord( [_.pointing_radec for _ in self.observations.list]) width = np.max( 5 * self.on_region.center.separation(pnt_radec).to_value("deg")) geom = WcsGeom.create( skydir=self.on_region.center, binsz=self.binsz, width=width, coordsys=coordsys, proj="TAN", ) plot_map = Map.from_geom(geom) if fig is None: fig = plt.figure(figsize=(7, 7)) if self.exclusion_mask is not None: coords = geom.get_coord() vals = self.exclusion_mask.get_by_coord(coords) plot_map.data += vals else: plot_map.data += 1.0 fig, ax, cbar = plot_map.plot(fig=fig, ax=ax, vmin=0, vmax=1) on_patch = self.on_region.to_pixel(wcs=geom.wcs).as_artist( edgecolor="red") ax.add_patch(on_patch) result = self.result obs_list = list(self.observations) if idx is not None: obs_list = np.asarray(self.observations)[idx] obs_list = np.atleast_1d(obs_list) result = np.asarray(self.result)[idx] result = np.atleast_1d(result) cmap = cmap or plt.get_cmap("viridis") colors = cmap(np.linspace(0, 1, len(self.observations))) handles = [] for idx_ in np.arange(len(obs_list)): obs = obs_list[idx_] off_regions = result[idx_].off_region for off in off_regions: off_patch = off.to_pixel(wcs=geom.wcs).as_artist( alpha=0.8, edgecolor=colors[idx_], label=f"Obs {obs.obs_id}") handle = ax.add_patch(off_patch) if off_regions: handles.append(handle) xx, yy = obs.pointing_radec.to_pixel(geom.wcs) ax.plot(xx, yy, marker="+", color=colors[idx_], markersize=20, linewidth=5) if add_legend: ax.legend(handles=handles) return fig, ax, cbar
def test_safe_mask_maker(observations, caplog): obs = observations[0] axis = MapAxis.from_bounds(0.1, 10, nbin=16, unit="TeV", name="energy", interp="log") axis_true = MapAxis.from_bounds(0.1, 50, nbin=30, unit="TeV", name="energy_true", interp="log") geom = WcsGeom.create(npix=(11, 11), axes=[axis], skydir=obs.pointing_radec) empty_dataset = MapDataset.create(geom=geom, energy_axis_true=axis_true) dataset_maker = MapDatasetMaker() safe_mask_maker = SafeMaskMaker(offset_max="3 deg", bias_percent=0.02, position=obs.pointing_radec) fixed_offset = 1.5 * u.deg safe_mask_maker_offset = SafeMaskMaker(offset_max="3 deg", bias_percent=0.02, fixed_offset=fixed_offset) dataset = dataset_maker.run(empty_dataset, obs) mask_offset = safe_mask_maker.make_mask_offset_max(dataset=dataset, observation=obs) assert_allclose(mask_offset.sum(), 109) mask_energy_aeff_default = safe_mask_maker.make_mask_energy_aeff_default( dataset=dataset, observation=obs) assert_allclose(mask_energy_aeff_default.data.sum(), 1936) mask_aeff_max = safe_mask_maker.make_mask_energy_aeff_max(dataset) mask_aeff_max_offset = safe_mask_maker_offset.make_mask_energy_aeff_max( dataset, obs) assert_allclose(mask_aeff_max.data.sum(), 1210) assert_allclose(mask_aeff_max_offset.data.sum(), 1210) mask_edisp_bias = safe_mask_maker.make_mask_energy_edisp_bias(dataset) mask_edisp_bias_offset = safe_mask_maker_offset.make_mask_energy_edisp_bias( dataset, obs) assert_allclose(mask_edisp_bias.data.sum(), 1815) assert_allclose(mask_edisp_bias_offset.data.sum(), 1694) mask_bkg_peak = safe_mask_maker.make_mask_energy_bkg_peak(dataset) assert_allclose(mask_bkg_peak.data.sum(), 1815) assert caplog.records[-1].levelname == "WARNING" assert caplog.records[ -1].message == "No default thresholds defined for obs 110380" safe_mask_maker_noroot = SafeMaskMaker(offset_max="3 deg", aeff_percent=-10, bias_percent=-10) mask_aeff_max_noroot = safe_mask_maker_noroot.make_mask_energy_aeff_max( dataset) mask_edisp_bias_noroot = safe_mask_maker_noroot.make_mask_energy_edisp_bias( dataset) assert_allclose(mask_aeff_max_noroot.data.sum(), 1815) assert_allclose(mask_edisp_bias_noroot.data.sum(), 1936)
def test_wcsndmap_crop(npix, binsz, frame, proj, skydir, axes): geom = WcsGeom.create(npix=npix, binsz=binsz, proj=proj, frame=frame, axes=axes) m = WcsNDMap(geom) m.crop(1)
data_store = DataStore.from_dir("$GAMMAPY_DATA/cta-1dc/index/gps/") obs_ids = [110380, 111140, 111159] obs_list = data_store.obs_list(obs_ids) # Now we define a reference geometry for our analysis, We choose a WCS based gemoetry with a binsize of 0.02 deg and also define an energy axis: # In[ ]: energy_axis = MapAxis.from_edges(np.logspace(-1., 1., 10), unit="TeV", name="energy", interp="log") geom = WcsGeom.create( skydir=(0, 0), binsz=0.02, width=(10, 8), coordsys="GAL", proj="CAR", axes=[energy_axis], ) # The `MapMaker` object is initialized with this reference geometry and a field of view cut of 4 deg: # In[ ]: get_ipython().run_cell_magic( 'time', '', 'maker = MapMaker(geom, offset_max=4. * u.deg)\nmaps = maker.run(obs_list)' ) # The maps are prepare by calling the `.run()` method and passing the observation list `obs_list`. The `.run()` method returns a Python `dict` containing a `counts`, `background` and `exposure` map:
def geom_image(): ebounds_true = np.logspace(-1.0, 1.0, 2) axis = MapAxis.from_edges(ebounds_true, name="energy", unit=u.TeV, interp="log") return WcsGeom.create( skydir=(0, 0), binsz=0.02, width=(2, 2), coordsys="GAL", axes=[axis] )
def exclusion_mask(): """Example mask for testing.""" pos = SkyCoord(83.63, 22.01, unit="deg", frame="icrs") exclusion_region = CircleSkyRegion(pos, Angle(0.3, "deg")) geom = WcsGeom.create(skydir=pos, binsz=0.02, width=10.0) return ~geom.region_mask([exclusion_region])
def test_get_axis_index_by_name(): e_axis = MapAxis.from_edges([1, 5], name="energy") geom = WcsGeom.create(width=5, binsz=1.0, axes=[e_axis]) assert geom.axes.index("energy") == 0 with pytest.raises(ValueError): geom.axes.index("time")
def test_memory_usage(): geom = WcsGeom.create() assert geom.data_nbytes().unit == u.MB assert_allclose(geom.data_nbytes(dtype="float32").value, 1.0368) assert_allclose(geom.data_nbytes(dtype="b").value, 0.2592)
# ## Maps # # Let's make some 3D cubes, as well as 2D images. # # For the energy, we make 5 bins from 1 TeV to 10 TeV. # In[ ]: energy_axis = MapAxis.from_edges(np.logspace(0, 1.0, 5), unit="TeV", name="energy", interp="log") geom = WcsGeom.create( skydir=(83.633, 22.014), binsz=0.02, width=(5, 5), coordsys="CEL", proj="TAN", axes=[energy_axis], ) # In[ ]: get_ipython().run_cell_magic( 'time', '', 'maker = MapMaker(geom, offset_max="2.5 deg")\nmaps = maker.run(observations)\nimages = maker.make_images()' ) # In[ ]: maps.keys()
def data_prep(): data_store = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/") OBS_ID = 23523 obs_ids = OBS_ID * np.ones(N_OBS) observations = data_store.get_observations(obs_ids) target_position = SkyCoord(ra=83.63, dec=22.01, unit="deg", frame="icrs") on_region_radius = Angle("0.11 deg") on_region = CircleSkyRegion(center=target_position, radius=on_region_radius) exclusion_region = CircleSkyRegion( center=SkyCoord(183.604, -8.708, unit="deg", frame="galactic"), radius=0.5 * u.deg, ) skydir = target_position.galactic mask_geom = WcsGeom.create( npix=(150, 150), binsz=0.05, skydir=skydir, proj="TAN", frame="galactic" ) exclusion_mask = mask_geom.region_mask([exclusion_region], inside=False) e_reco = MapAxis.from_bounds( 0.1, 40, nbin=40, interp="log", unit="TeV", name="energy" ) e_true = MapAxis.from_bounds( 0.05, 100, nbin=200, interp="log", unit="TeV", name="energy_true" ) geom = RegionGeom(on_region, axes=[e_reco]) stacked = SpectrumDatasetOnOff.create(geom=geom, energy_axis_true=e_true, name="stacked") dataset_maker = SpectrumDatasetMaker( containment_correction=False, selection=["counts", "exposure", "edisp"] ) bkg_maker = ReflectedRegionsBackgroundMaker(exclusion_mask=exclusion_mask) safe_mask_masker = SafeMaskMaker(methods=["aeff-max"], aeff_percent=10) spectral_model = PowerLawSpectralModel( index=2, amplitude=2e-11 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV ) spatial_model = PointSpatialModel( lon_0=target_position.ra, lat_0=target_position.dec, frame="icrs" ) spatial_model.lon_0.frozen = True spatial_model.lat_0.frozen = True sky_model = SkyModel( spatial_model=spatial_model, spectral_model=spectral_model, name="" ) for observation in observations: dataset = stacked.copy(name=f"dataset-{observation.obs_id}") dataset = dataset_maker.run(dataset=dataset, observation=observation) dataset_on_off = bkg_maker.run(dataset, observation) dataset_on_off = safe_mask_masker.run(dataset_on_off, observation) stacked.stack(dataset_on_off) stacked.models = sky_model return Datasets([stacked])
def geom_true(): axis = MapAxis.from_edges(np.logspace(-1, 1, 4), unit=u.TeV, name="energy_true") return WcsGeom.create(skydir=(0, 0), npix=(5, 4), frame="galactic", axes=[axis])
def test_evaluate_fk5_model(): geom = WcsGeom.create(width=(5, 5), binsz=0.1, coordsys="CEL") model = GaussianSpatialModel("0 deg", "0 deg", "0.1 deg", frame="fk5") data = model.evaluate_geom(geom) assert data.sum() > 0
"""Example 3D analysis using gammapy.maps. """ import numpy as np from numpy.testing import assert_allclose import astropy.units as u from gammapy.data import DataStore from gammapy.maps import WcsGeom, MapAxis from gammapy.cube import MapMaker axis = MapAxis.from_edges(np.logspace(-1., 1., 10), unit=u.TeV) geom = WcsGeom.create(skydir=(0, 0), binsz=0.02, width=15., coordsys='GAL', axes=[axis]) maker = MapMaker(geom, 4. * u.deg) ds = DataStore.from_dir('$GAMMAPY_EXTRA/datasets/cta-1dc/index/gps/') # obs_ids = [110380, 111140, 111159] # obs_ids = [110380, 111140] obs_ids = [110380] for obs_id in obs_ids: print(obs_id) obs = ds.obs(obs_id) maker.process_obs(obs) filename = 'counts.fits' print(f'Writing {filename}') maker.count_map.to_hdulist().writeto(filename, overwrite=True)
def test_interpolate_map_dataset(): energy = MapAxis.from_energy_bounds("1 TeV", "300 TeV", nbin=5, name="energy") energy_true = MapAxis.from_nodes( np.logspace(-1, 3, 20), name="energy_true", interp="log", unit="TeV" ) # make dummy map IRFs geom_allsky = WcsGeom.create( npix=(5, 3), proj="CAR", binsz=60, axes=[energy], skydir=(0, 0) ) geom_allsky_true = geom_allsky.drop("energy").to_cube([energy_true]) # background geom_background = WcsGeom.create( skydir=(0, 0), width=(5, 5), binsz=0.2 * u.deg, axes=[energy] ) value = 30 bkg_map = Map.from_geom(geom_background, unit="") bkg_map.data = value * np.ones(bkg_map.data.shape) # effective area - with a gradient that also depends on energy aeff_map = Map.from_geom(geom_allsky_true, unit="cm2 s") ra_arr = np.arange(aeff_map.data.shape[1]) dec_arr = np.arange(aeff_map.data.shape[2]) for i in np.arange(aeff_map.data.shape[0]): aeff_map.data[i, :, :] = ( (i + 1) * 10 * np.meshgrid(dec_arr, ra_arr)[0] + 10 * np.meshgrid(dec_arr, ra_arr)[1] + 10 ) aeff_map.meta["TELESCOP"] = "HAWC" # psf map width = 0.2 * u.deg rad_axis = MapAxis.from_nodes(np.linspace(0, 2, 50), name="rad", unit="deg") psfMap = PSFMap.from_gauss(energy_true, rad_axis, width) # edispmap edispmap = EDispKernelMap.from_gauss( energy, energy_true, sigma=0.1, bias=0.0, geom=geom_allsky ) # events and gti nr_ev = 10 ev_t = Table() gti_t = Table() ev_t["EVENT_ID"] = np.arange(nr_ev) ev_t["TIME"] = nr_ev * [Time("2011-01-01 00:00:00", scale="utc", format="iso")] ev_t["RA"] = np.linspace(-1, 1, nr_ev) * u.deg ev_t["DEC"] = np.linspace(-1, 1, nr_ev) * u.deg ev_t["ENERGY"] = np.logspace(0, 2, nr_ev) * u.TeV gti_t["START"] = [Time("2010-12-31 00:00:00", scale="utc", format="iso")] gti_t["STOP"] = [Time("2011-01-02 00:00:00", scale="utc", format="iso")] events = EventList(ev_t) gti = GTI(gti_t) # define observation obs = Observation( obs_id=0, obs_info={}, gti=gti, aeff=aeff_map, edisp=edispmap, psf=psfMap, bkg=bkg_map, events=events, obs_filter=None, ) # define analysis geometry geom_target = WcsGeom.create( skydir=(0, 0), width=(5, 5), binsz=0.1 * u.deg, axes=[energy] ) maker = MapDatasetMaker( selection=["exposure", "counts", "background", "edisp", "psf"] ) dataset = MapDataset.create( geom=geom_target, energy_axis_true=energy_true, rad_axis=rad_axis, name="test" ) dataset = maker.run(dataset, obs) # test counts assert dataset.counts.data.sum() == nr_ev # test background assert np.floor(np.sum(dataset.npred_background().data)) == np.sum(bkg_map.data) coords_bg = {"skycoord": SkyCoord("0 deg", "0 deg"), "energy": energy.center[0]} assert_allclose( dataset.npred_background().get_by_coord(coords_bg)[0], 7.5, atol=1e-4 ) # test effective area coords_aeff = { "skycoord": SkyCoord("0 deg", "0 deg"), "energy_true": energy_true.center[0], } assert_allclose( aeff_map.get_by_coord(coords_aeff)[0], dataset.exposure.interp_by_coord(coords_aeff)[0], atol=1e-3, ) # test edispmap pdfmatrix_preinterp = edispmap.get_edisp_kernel( SkyCoord("0 deg", "0 deg") ).pdf_matrix pdfmatrix_postinterp = dataset.edisp.get_edisp_kernel( SkyCoord("0 deg", "0 deg") ).pdf_matrix assert_allclose(pdfmatrix_preinterp, pdfmatrix_postinterp, atol=1e-7) # test psfmap geom_psf = geom_target.drop("energy").to_cube([energy_true]) psfkernel_preinterp = psfMap.get_psf_kernel( position=SkyCoord("0 deg", "0 deg"), geom=geom_psf, max_radius=2 * u.deg ).data psfkernel_postinterp = dataset.psf.get_psf_kernel( position=SkyCoord("0 deg", "0 deg"), geom=geom_psf, max_radius=2 * u.deg ).data assert_allclose(psfkernel_preinterp, psfkernel_postinterp, atol=1e-4)
def setup(self): etrue = np.logspace(-1, 1, 10) * u.TeV self.e_true = MapAxis.from_energy_edges(etrue, name="energy_true") ereco = np.logspace(-1, 1, 5) * u.TeV elo = ereco[:-1] ehi = ereco[1:] self.e_reco = MapAxis.from_energy_edges(ereco, name="energy") start = u.Quantity([0], "s") stop = u.Quantity([1000], "s") time_ref = Time("2010-01-01 00:00:00.0") self.gti = GTI.create(start, stop, time_ref) self.livetime = self.gti.time_sum self.on_region = make_region("icrs;circle(0.,1.,0.1)") off_region = make_region("icrs;box(0.,1.,0.1, 0.2,30)") self.off_region = off_region.union( make_region("icrs;box(-1.,-1.,0.1, 0.2,150)") ) self.wcs = WcsGeom.create(npix=300, binsz=0.01, frame="icrs").wcs self.aeff = RegionNDMap.create( region=self.on_region, wcs=self.wcs, axes=[self.e_true], unit="cm2" ) self.aeff.data += 1 data = np.ones(elo.shape) data[-1] = 0 # to test stats calculation with empty bins axis = MapAxis.from_edges(ereco, name="energy", interp="log") self.on_counts = RegionNDMap.create( region=self.on_region, wcs=self.wcs, axes=[axis], meta={"EXPOSURE": self.livetime.to_value("s")}, ) self.on_counts.data += 1 self.on_counts.data[-1] = 0 self.off_counts = RegionNDMap.create( region=self.off_region, wcs=self.wcs, axes=[axis] ) self.off_counts.data += 10 acceptance = RegionNDMap.from_geom(self.on_counts.geom) acceptance.data += 1 data = np.ones(elo.shape) data[-1] = 0 acceptance_off = RegionNDMap.from_geom(self.off_counts.geom) acceptance_off.data += 10 self.edisp = EDispKernelMap.from_diagonal_response( self.e_reco, self.e_true, self.on_counts.geom.to_image() ) exposure = self.aeff * self.livetime exposure.meta["livetime"] = self.livetime self.dataset = SpectrumDatasetOnOff( counts=self.on_counts, counts_off=self.off_counts, exposure=exposure, edisp=self.edisp, acceptance=acceptance, acceptance_off=acceptance_off, name="test", gti=self.gti, )
def geom_true(): axis = MapAxis.from_edges(np.logspace(-1, 1, 4), unit=u.TeV, name="energy") return WcsGeom.create(skydir=(0, 0), npix=(5, 4), coordsys="GAL", axes=[axis])
def to_wcs_tiles(self, nside_tiles=4, margin="0 deg"): """Create WCS tiles geometries from HPX geometry with given nside. The HEALPix geom is divide into superpixels defined by nside_tiles, which are then represented by a WCS geometry using a tangential projection. The number of WCS tiles is given by the number of pixels for the given nside_tiles. Parameters ---------- nside_tiles : int Nside for super pixel tiles. Usually nsi margin : Angle Width margin of the wcs tile Return ------ wcs_tiles : list List of WCS tile geoms. """ import healpy as hp from gammapy.maps import WcsGeom margin = u.Quantity(margin) if nside_tiles >= self.nside: raise ValueError(f"nside_tiles must be < {self.nside}") if not self.is_allsky: raise ValueError( "to_wcs_tiles() is only supported for all sky geoms") binsz = np.degrees(hp.nside2resol(self.nside)) * u.deg hpx = self.to_image().to_nside(nside=nside_tiles) wcs_tiles = [] for pix in range(int(hpx.npix)): skydir = hpx.pix_to_coord([pix]) vtx = hp.boundaries(nside=hpx.nside, pix=pix, nest=hpx.nest, step=1) lon, lat = hp.vec2ang(vtx.T, lonlat=True) boundaries = SkyCoord(lon * u.deg, lat * u.deg, frame=hpx.frame) # Compute maximum separation between all pairs of boundaries and take it # as width width = boundaries.separation(boundaries[:, np.newaxis]).max() wcs_tile_geom = WcsGeom.create(skydir=(float(skydir[0]), float(skydir[1])), width=width + margin, binsz=binsz, frame=hpx.frame, proj="TAN", axes=self.axes) wcs_tiles.append(wcs_tile_geom) return wcs_tiles
def test_wcs_geom_pad(): axis = MapAxis.from_bounds(0, 1, nbin=1, name="axis", unit="") geom = WcsGeom.create(skydir=(0, 0), npix=10, binsz=0.1, axes=[axis]) geom_pad = geom.pad(axis_name="axis", pad_width=1) assert_allclose(geom_pad.axes["axis"].edges, [-1, 0, 1, 2])
def geom(): return WcsGeom.create(binsz=0.5, npix=10)
def test_interp_to_geom(): energy = MapAxis.from_energy_bounds("1 TeV", "300 TeV", nbin=5, name="energy") energy_target = MapAxis.from_energy_bounds("1 TeV", "300 TeV", nbin=7, name="energy") value = 30 coords = { "skycoord": SkyCoord("0 deg", "0 deg"), "energy": energy_target.center[3] } # WcsNDMap geom_wcs = WcsGeom.create(npix=(5, 3), proj="CAR", binsz=60, axes=[energy], skydir=(0, 0)) wcs_map = Map.from_geom(geom_wcs, unit="") wcs_map.data = value * np.ones(wcs_map.data.shape) wcs_geom_target = WcsGeom.create(skydir=(0, 0), width=(10, 10), binsz=0.1 * u.deg, axes=[energy_target]) interp_wcs_map = wcs_map.interp_to_geom(wcs_geom_target, method="linear") assert_allclose(interp_wcs_map.get_by_coord(coords)[0], value, atol=1e-7) assert isinstance(interp_wcs_map, WcsNDMap) assert interp_wcs_map.geom == wcs_geom_target # HpxNDMap geom_hpx = HpxGeom.create(binsz=60, axes=[energy], skydir=(0, 0)) hpx_map = Map.from_geom(geom_hpx, unit="") hpx_map.data = value * np.ones(hpx_map.data.shape) hpx_geom_target = HpxGeom.create(skydir=(0, 0), width=10, binsz=0.1 * u.deg, axes=[energy_target]) interp_hpx_map = hpx_map.interp_to_geom(hpx_geom_target) assert_allclose(interp_hpx_map.get_by_coord(coords)[0], value, atol=1e-7) assert isinstance(interp_hpx_map, HpxNDMap) assert interp_hpx_map.geom == hpx_geom_target # Preserving the counts binsz = 0.2 * u.deg geom_initial = WcsGeom.create( skydir=(20, 20), width=(1, 1), binsz=0.2 * u.deg, ) factor = 2 test_map = Map.from_geom(geom_initial, unit="") test_map.data = value * np.eye(test_map.data.shape[0]) geom_target = WcsGeom.create( skydir=(20, 20), width=(1.5, 1.5), binsz=binsz / factor, ) new_map = test_map.interp_to_geom(geom_target, fill_value=0., method="nearest", preserve_counts=True) assert_allclose(new_map.data[8, 8], test_map.data[4, 4] / factor**2, rtol=1e-4) assert_allclose(new_map.data[0, 8], 0., rtol=1e-4)
def make_datasets_example(): # Define which data to use and print some information energy_axis = MapAxis.from_edges( np.logspace(-1.0, 1.0, 4), unit="TeV", name="energy", interp="log" ) geom0 = WcsGeom.create( skydir=(0, 0), binsz=0.1, width=(1, 1), frame="galactic", proj="CAR", axes=[energy_axis], ) geom1 = WcsGeom.create( skydir=(1, 0), binsz=0.1, width=(1, 1), frame="galactic", proj="CAR", axes=[energy_axis], ) geoms = [geom0, geom1] sources_coords = [(0, 0), (0.9, 0.1)] names = ["gc", "g09"] models = [] for idx, (lon, lat) in enumerate(sources_coords): spatial_model = PointSpatialModel( lon_0=lon * u.deg, lat_0=lat * u.deg, frame="galactic" ) spectral_model = ExpCutoffPowerLawSpectralModel( index=2 * u.Unit(""), amplitude=3e-12 * u.Unit("cm-2 s-1 TeV-1"), reference=1.0 * u.TeV, lambda_=0.1 / u.TeV, ) model_ecpl = SkyModel( spatial_model=spatial_model, spectral_model=spectral_model, name=names[idx] ) models.append(model_ecpl) # test to link a spectral parameter params0 = models[0].spectral_model.parameters params1 = models[1].spectral_model.parameters params0.link("reference", params1["reference"]) # update the sky model models[0].parameters.link("reference", params1["reference"]) obs_ids = [110380, 111140, 111159] data_store = DataStore.from_dir("$GAMMAPY_DATA/cta-1dc/index/gps/") diffuse_model = SkyDiffuseCube.read( "$GAMMAPY_DATA/fermi_3fhl/gll_iem_v06_cutout.fits" ) datasets_list = [] for idx, geom in enumerate(geoms): observations = data_store.get_observations(obs_ids) stacked = MapDataset.create(geom=geom) stacked.background_model.name = "background_irf_" + names[idx] maker = MapDatasetMaker(offset_max=4.0 * u.deg) for obs in observations: dataset = maker.run(stacked, obs) stacked.stack(dataset) stacked.psf = stacked.psf.get_psf_kernel( position=geom.center_skydir, geom=geom, max_radius="0.3 deg" ) stacked.name = names[idx] stacked.models = models[idx] + diffuse_model datasets_list.append(stacked) datasets = Datasets(datasets_list) dataset0 = datasets[0] print("dataset0") print("counts sum : ", dataset0.counts.data.sum()) print("expo sum : ", dataset0.exposure.data.sum()) print("bkg0 sum : ", dataset0.background_model.evaluate().data.sum()) datasets.write("$GAMMAPY_DATA/tests/models", prefix="gc_example_", overwrite=True)
# ## Make sky images # # ### Define map geometry # # Select the target position and define an ON region for the spectral analysis # In[ ]: axis = MapAxis.from_edges(np.logspace(-1.0, 1.0, 10), unit="TeV", name="energy", interp="log") geom = WcsGeom.create(skydir=(0, 0), npix=(500, 400), binsz=0.02, coordsys="GAL", axes=[axis]) geom # ### Compute images # # Exclusion mask currently unused. Remove here or move to later in the tutorial? # In[ ]: target_position = SkyCoord(0, 0, unit="deg", frame="galactic") on_radius = 0.2 * u.deg on_region = CircleSkyRegion(center=target_position, radius=on_radius) # In[ ]:
npix_irreg = np.vstack((np.arange(2,10,2),np.arange(2,10,2))).T cdelt_irreg = cdelt*np.vstack((np.linspace(4.,1.,4),np.linspace(4.,1.,4))).T crpix_irreg = (npix_irreg+1)/2. tab_bands = create_bands_table(emin, emax, npix_irreg, cdelt_irreg, crpix_irreg) hdulist = [hdu, fits.table_to_hdu(tab_bands)] update_header(hdulist[1].header, **{}) fits.HDUList(hdulist).writeto('wcs_ccube_irregular.fits', overwrite=True) ################################# # WCS Cube Sparse from gammapy.maps import WcsMapND, WcsGeom geom = WcsGeom.create(npix=npix, axes=[egy]) m = WcsMapND(geom, data) m.write('test_sparse.fits',sparse=True) data_flat = np.ravel(data).reshape(data.shape[:-2] + (data.shape[-1] * data.shape[-2],)) nonzero = np.where(data_flat > 0) channel = np.ravel_multi_index(nonzero[:-1], data.shape[:-2]) cols = [Column(name='PIX', data=nonzero[1], dtype='i4'), Column(name='CHANNEL', data=nonzero[0], dtype='i2'), Column(name='VALUE', data=data_flat[nonzero], dtype='f8')] tab_sparse = Table(cols, meta={'EXTNAME' : 'SKYMAP'}) # Write File tab_bands = create_bands_table(emin, emax)
### Energy axes and size energy_axis = MapAxis.from_bounds(0.2e5, 250e6, 40, interp='log', name='energy', unit='MeV') enlarger = 1.2 r_0 = rad_interpolate(energy_axis.center) * u.deg * enlarger r_0 = np.where(r_0>=0, r_0, 0) * u.deg ### Fill the index and normalization at the positions of the pixels binsize=0.02 eccentricity = 0.69 ang = 45. width = 3. m_wcs = WcsGeom.create(binsz=binsize, coordsys="CEL", skydir=position_psr, width=width*u.deg, axes=[energy_axis]) model = DiskSpatialModel(lon_0=ra_0_psr*u.deg, lat_0=dec_0_psr*u.deg, r_0="1.1 deg", e=eccentricity, phi=ang * u.deg, frame="icrs") coords = m_wcs.get_coord() coord_map = SkyCoord(coords.lon, coords.lat, frame='icrs') separation = position_psr.separation(coord_map) new_indexes = indexes(separation.value) N0 = (fluxes(separation.value) * (1-new_indexes) / ((emax/E_ref)**(1-new_indexes) - (emin/E_ref)**(1-new_indexes))) / (0.26 * np.pi / 180.)**2 ### Create the map skymap = Map.create(width=width*u.deg, axes=[energy_axis],
def test_sky_disk(): # Test the disk case (e=0) r_0 = 2 * u.deg model = DiskSpatialModel(lon_0="1 deg", lat_0="45 deg", r_0=r_0) lon = [1, 5, 359] * u.deg lat = 46 * u.deg val = model(lon, lat) assert val.unit == "sr-1" desired = [261.263956, 0, 261.263956] assert_allclose(val.value, desired) radius = model.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.to_value("deg"), 2.222) assert_allclose(model.evaluation_bin_size_min, 0.198 * u.deg) # test the normalization for an elongated ellipse near the Galactic Plane m_geom_1 = WcsGeom.create(binsz=0.015, width=(20, 20), skydir=(2, 2), frame="galactic", proj="AIT") coords = m_geom_1.get_coord() solid_angle = m_geom_1.solid_angle() lon = coords.lon lat = coords.lat r_0 = 10 * u.deg model_1 = DiskSpatialModel(lon_0=2 * u.deg, lat_0=2 * u.deg, r_0=r_0, e=0.4, phi=30 * u.deg) vals_1 = model_1(lon, lat) assert vals_1.unit == "sr-1" assert_allclose(np.sum(vals_1 * solid_angle), 1, rtol=1.0e-3) radius = model_1.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.to_value("deg"), 11.11) # test rotation r_0 = 2 * u.deg semi_minor = 1 * u.deg eccentricity = np.sqrt(1 - (semi_minor / r_0)**2) model_rot_test = DiskSpatialModel(lon_0=0 * u.deg, lat_0=0 * u.deg, r_0=r_0, e=eccentricity, phi=90 * u.deg) assert_allclose(model_rot_test(0 * u.deg, 1.5 * u.deg).value, 0) # test the normalization for a disk (ellipse with e=0) at the Galactic Pole m_geom_2 = WcsGeom.create(binsz=0.1, width=(6, 6), skydir=(0, 90), frame="galactic", proj="AIT") coords = m_geom_2.get_coord() lon = coords.lon lat = coords.lat r_0 = 5 * u.deg disk = DiskSpatialModel(lon_0=0 * u.deg, lat_0=90 * u.deg, r_0=r_0) vals_disk = disk(lon, lat) solid_angle = 2 * np.pi * (1 - np.cos(5 * u.deg)) assert_allclose(np.max(vals_disk).value * solid_angle, 1) assert isinstance(model.to_region(), EllipseSkyRegion)
def test_wcsndmap_upsample(npix, binsz, frame, proj, skydir, axes): geom = WcsGeom.create(npix=npix, binsz=binsz, proj=proj, frame=frame, axes=axes) m = WcsNDMap(geom, unit="m2") m2 = m.upsample(2, preserve_counts=True) assert_allclose(np.nansum(m.data), np.nansum(m2.data)) assert m.unit == m2.unit
def test_sky_gaussian(): # Test symmetric model sigma = 1 * u.deg model = GaussianSpatialModel(lon_0="5 deg", lat_0="15 deg", sigma=sigma) assert model.parameters["sigma"].min == 0 val_0 = model(5 * u.deg, 15 * u.deg) val_sigma = model(5 * u.deg, 16 * u.deg) assert val_0.unit == "sr-1" ratio = val_0 / val_sigma assert_allclose(ratio, np.exp(0.5)) radius = model.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.value, 5 * sigma.value) assert_allclose(model.evaluation_bin_size_min, (1. / 3.) * u.deg) # test the normalization for an elongated Gaussian near the Galactic Plane m_geom_1 = WcsGeom.create(binsz=0.05, width=(20, 20), skydir=(2, 2), frame="galactic", proj="AIT") coords = m_geom_1.get_coord() solid_angle = m_geom_1.solid_angle() lon = coords.lon lat = coords.lat sigma = 3 * u.deg model_1 = GaussianSpatialModel(lon_0=2 * u.deg, lat_0=2 * u.deg, sigma=sigma, e=0.8, phi=30 * u.deg) vals_1 = model_1(lon, lat) assert vals_1.unit == "sr-1" assert_allclose(np.sum(vals_1 * solid_angle), 1, rtol=1.0e-3) radius = model_1.evaluation_radius assert radius.unit == "deg" assert_allclose(radius.value, 5 * sigma.value) # check the ratio between the value at the peak and on the 1-sigma isocontour sigma = 4 * u.deg semi_minor = 2 * u.deg e = np.sqrt(1 - (semi_minor / sigma)**2) model_2 = GaussianSpatialModel(lon_0=0 * u.deg, lat_0=0 * u.deg, sigma=sigma, e=e, phi=0 * u.deg) val_0 = model_2(0 * u.deg, 0 * u.deg) val_major = model_2(0 * u.deg, 4 * u.deg) val_minor = model_2(2 * u.deg, 0 * u.deg) assert val_0.unit == "sr-1" ratio_major = val_0 / val_major ratio_minor = val_0 / val_minor assert_allclose(ratio_major, np.exp(0.5)) assert_allclose(ratio_minor, np.exp(0.5)) # check the rotation model_3 = GaussianSpatialModel(lon_0=0 * u.deg, lat_0=0 * u.deg, sigma=sigma, e=e, phi=90 * u.deg) val_minor_rotated = model_3(0 * u.deg, 2 * u.deg) ratio_minor_rotated = val_0 / val_minor_rotated assert_allclose(ratio_minor_rotated, np.exp(0.5)) assert isinstance(model.to_region(), EllipseSkyRegion)
# ## J Factors # # There are utilies to compute J-Factor maps can can serve as a basis to compute J-Factors for certain regions. In the following we compute a J-Factor map for the Galactic Centre region # In[ ]: profile = profiles.NFWProfile() # Adopt standard values used in HESS profiles.DMProfile.DISTANCE_GC = 8.5 * u.kpc profiles.DMProfile.LOCAL_DENSITY = 0.39 * u.Unit("GeV / cm3") profile.scale_to_local_density() position = SkyCoord(0.0, 0.0, frame="galactic", unit="deg") geom = WcsGeom.create(binsz=0.05, skydir=position, width=3.0, coordsys="GAL") # In[ ]: jfactory = JFactory(geom=geom, profile=profile, distance=profiles.DMProfile.DISTANCE_GC) jfact = jfactory.compute_jfactor() # In[ ]: jfact_map = WcsNDMap(geom=geom, data=jfact.value, unit=jfact.unit) fig, ax, im = jfact_map.plot(cmap="viridis", norm=LogNorm(), add_cbar=True) plt.title("J-Factor [{}]".format(jfact_map.unit)) # 1 deg circle usually used in H.E.S.S. analyses
# ------------ # Here is an example plot of the model: from astropy.coordinates import SkyCoord from gammapy.maps import WcsGeom from gammapy.modeling.models import ( Models, PointSpatialModel, PowerLawSpectralModel, SkyModel, ) model = PointSpatialModel(lon_0="0.01 deg", lat_0="0.01 deg", frame="galactic",) geom = WcsGeom.create( skydir=SkyCoord("0d 0d", frame="galactic"), width=(1, 1), binsz=0.1 ) model.plot(geom=geom, add_cbar=True) #%% # YAML representation # ------------------- # Here is an example YAML file using the model: pwl = PowerLawSpectralModel() point = PointSpatialModel() model = SkyModel(spectral_model=pwl, spatial_model=point, name="pwl-point-model") models = Models([model]) print(models.to_yaml())
amplitude="1e-11 cm-2 s-1 TeV-1", reference="1 TeV") sky_model = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model) print(sky_model) # In[ ]: # Define map geometry axis = MapAxis.from_edges(np.logspace(-1.0, 1.0, 10), unit="TeV", name="energy", interp="log") geom = WcsGeom.create(skydir=(0, 0), binsz=0.02, width=(5, 4), coordsys="GAL", axes=[axis]) # In[ ]: # Define some observation parameters # We read in the pointing info from one of the 1dc event list files as an example pointing = FixedPointingInfo.read( "$GAMMAPY_DATA/cta-1dc/data/baseline/gps/gps_baseline_110380.fits") livetime = 1 * u.hour offset_max = 2 * u.deg offset = Angle("2 deg") # In[ ]:
def test_wcsgeom_squash(): axis = MapAxis.from_nodes([1, 2, 3], name="test-axis") geom = WcsGeom.create(npix=(3, 3), axes=[axis]) geom_squashed = geom.squash(axis_name="test-axis") assert geom_squashed.data_shape == (1, 3, 3)
) spectral_model_2 = PowerLaw( index=3, amplitude="1e-11 cm-2 s-1 TeV-1", reference="1 TeV" ) sky_model_1 = SkyModel(spatial_model=spatial_model_1, spectral_model=spectral_model_1) sky_model_2 = SkyModel(spatial_model=spatial_model_2, spectral_model=spectral_model_2) models = sky_model_1 + sky_model_2 # Define map geometry axis = MapAxis.from_edges(np.logspace(-1.0, 1.0, 10), unit="TeV") geom = WcsGeom.create( skydir=(0, 0), binsz=0.02, width=(2, 2), coordsys="GAL", axes=[axis] ) # Define some observation parameters # we are not simulating many pointings / observations pointing = SkyCoord(0.2, 0.5, unit="deg", frame="galactic") livetime = 20 * u.hour exposure_map = make_map_exposure_true_energy( pointing=pointing, livetime=livetime, aeff=aeff, geom=geom ) evaluator = MapEvaluator(model=models, exposure=exposure_map)
"""Plot Fermi PSF.""" import matplotlib.pyplot as plt from gammapy.irf import EnergyDependentTablePSF from gammapy.maps import WcsGeom from gammapy.cube import PSFKernel filename = "$GAMMAPY_DATA/tests/unbundled/fermi/psf.fits" fermi_psf = EnergyDependentTablePSF.read(filename) psf = fermi_psf.table_psf_at_energy(energy="1 GeV") geom = WcsGeom.create(npix=100, binsz=0.01) kernel = PSFKernel.from_table_psf(psf, geom) plt.imshow(kernel.data) plt.colorbar() plt.show()