def get_npred_map(): position = SkyCoord(0.0, 0.0, frame="galactic", unit="deg") energy_axis = MapAxis.from_bounds(1, 100, nbin=30, unit="TeV", name="energy_true", interp="log") exposure = Map.create( binsz=0.02, map_type="wcs", skydir=position, width="2 deg", axes=[energy_axis], frame="galactic", unit="cm2 s", ) spatial_model = GaussianSpatialModel(lon_0="0 deg", lat_0="0 deg", sigma="0.2 deg", frame="galactic") spectral_model = PowerLawSpectralModel(amplitude="1e-11 cm-2 s-1 TeV-1") skymodel = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model) exposure.data = 1e14 * np.ones(exposure.data.shape) evaluator = MapEvaluator(model=skymodel, exposure=exposure) npred = evaluator.compute_npred() return evaluator, npred
def test_map_slice_by_idx(binsz, width, map_type, skydir, axes, unit): m = Map.create(binsz=binsz, width=width, map_type=map_type, skydir=skydir, axes=axes, unit=unit) data = np.arange(m.data.size, dtype=float) m.data = data.reshape(m.data.shape) # Test none slicing sliced = m.slice_by_idx({}) assert_equal(m.geom.shape_axes, sliced.geom.shape_axes) slices = {"energy": slice(0, 1), "time": slice(0, 2)} sliced = m.slice_by_idx(slices) assert not sliced.geom.is_image slices = tuple([slices[ax.name] for ax in m.geom.axes]) assert_equal(m.data[slices[::-1]], sliced.data) assert sliced.data.base is data slices = {"energy": 0, "time": 1} sliced = m.slice_by_idx(slices) assert sliced.geom.is_image slices = tuple([slices[ax.name] for ax in m.geom.axes]) assert_equal(m.data[slices[::-1]], sliced.data) assert sliced.data.base is data
def test_sky_point_source(): # Test special case of point source. Regression test for GH 2367. energy_axis = MapAxis.from_edges([1, 10], unit="TeV", name="energy", interp="log") exposure = Map.create( skydir=(100, 70), npix=(4, 4), binsz=0.1, proj="AIT", unit="cm2 s", axes=[energy_axis], ) exposure.data = np.ones_like(exposure.data) spatial_model = PointSpatialModel( lon_0=100.06 * u.deg, lat_0=70.03 * u.deg, frame="icrs" ) # Create a spectral model with integral flux of 1 cm-2 s-1 in this energy band spectral_model = ConstantSpectralModel(const="1 cm-2 s-1 TeV-1") spectral_model.const.value /= spectral_model.integral(1 * u.TeV, 10 * u.TeV).value model = SkyModel(spatial_model=spatial_model, spectral_model=spectral_model) evaluator = MapEvaluator(model=model, exposure=exposure) flux = evaluator.compute_flux().to_value("cm-2 s-1")[0] expected = [ [0, 0, 0, 0], [0, 0.140, 0.058, 0.0], [0, 0.564, 0.236, 0], [0, 0, 0, 0], ] assert_allclose(flux, expected, atol=0.01) assert_allclose(flux.sum(), 1)
def diffuse_model(): axis = MapAxis.from_nodes([0.1, 100], name="energy", unit="TeV", interp="log") m = Map.create( npix=(4, 3), binsz=2, axes=[axis], unit="cm-2 s-1 MeV-1 sr-1", frame="galactic" ) m.data += 42 return SkyDiffuseCube(m)
def make_all_models(): """Make an instance of each model, for testing.""" yield Model.create("ConstantSpatialModel") yield Model.create("TemplateSpatialModel", map=Map.create(npix=(10, 20))) yield Model.create("DiskSpatialModel", lon_0="1 deg", lat_0="2 deg", r_0="3 deg") yield Model.create("GaussianSpatialModel", lon_0="1 deg", lat_0="2 deg", sigma="3 deg") yield Model.create("PointSpatialModel", lon_0="1 deg", lat_0="2 deg") yield Model.create("ShellSpatialModel", lon_0="1 deg", lat_0="2 deg", radius="3 deg", width="4 deg") yield Model.create("ConstantSpectralModel", const="99 cm-2 s-1 TeV-1") # TODO: yield Model.create("CompoundSpectralModel") yield Model.create("PowerLawSpectralModel") yield Model.create("PowerLaw2SpectralModel") yield Model.create("ExpCutoffPowerLawSpectralModel") yield Model.create("ExpCutoffPowerLaw3FGLSpectralModel") yield Model.create("SuperExpCutoffPowerLaw3FGLSpectralModel") yield Model.create("SuperExpCutoffPowerLaw4FGLSpectralModel") yield Model.create("LogParabolaSpectralModel") yield Model.create("TemplateSpectralModel", energy=[1, 2] * u.cm, values=[3, 4] * u.cm) # TODO: add unit validation? yield Model.create("GaussianSpectralModel") # TODO: yield Model.create("AbsorbedSpectralModel") # TODO: yield Model.create("NaimaSpectralModel") # TODO: yield Model.create("ScaleSpectralModel") yield Model.create("ConstantTemporalModel") yield Model.create("LightCurveTemplateTemporalModel", Table()) yield Model.create( "SkyModel", spatial_model=Model.create("ConstantSpatialModel"), spectral_model=Model.create("PowerLawSpectralModel"), ) m1 = Map.create(npix=(10, 20, 30), axes=[MapAxis.from_nodes([1, 2] * u.TeV, name="energy")]) yield Model.create("SkyDiffuseCube", map=m1) m2 = Map.create(npix=(10, 20, 30), axes=[MapAxis.from_edges([1, 2] * u.TeV, name="energy")]) yield Model.create("BackgroundModel", map=m2)
def test_map_fill_events_uint_column(events): # Check that unsigned int column works. # Regression test for https://github.com/gammapy/gammapy/issues/1620 axis = MapAxis.from_edges([0, 3, 6], name="event_id") m = Map.create(npix=(2, 1), binsz=10, axes=[axis]) m.fill_events(events) assert m.data.sum() == 1 assert_allclose(m.data[0, 0, 0], 1)
def diffuse_model(): axis = MapAxis.from_nodes([0.1, 100], name="energy_true", unit="TeV", interp="log") m = Map.create( npix=(4, 3), binsz=2, axes=[axis], unit="cm-2 s-1 MeV-1 sr-1", frame="galactic" ) m.data += 42 spatial_model = TemplateSpatialModel(m, normalize=False) return SkyModel(PowerLawNormSpectralModel(), spatial_model)
def test_map_create(binsz, width, map_type, skydir, axes, unit): m = Map.create(binsz=binsz, width=width, map_type=map_type, skydir=skydir, axes=axes, unit=unit) assert m.unit == unit
def test_wcsndmap_interp_by_coord_fill_value(): # Introduced in https://github.com/gammapy/gammapy/pull/1559/files m = Map.create(npix=(20, 10)) m.data += 42 # With `fill_value` one should be able to control what gets filled assert_allclose(m.interp_by_coord((99, 0), fill_value=99), 99) # Default is to extrapolate assert_allclose(m.interp_by_coord((99, 0)), 42)
def test_sky_diffuse_map_normalize(): # define model map with a constant value of 1 model_map = Map.create(map_type="wcs", width=(10, 5), binsz=0.5, unit="sr-1") model_map.data += 1.0 model = TemplateSpatialModel(model_map) # define data map with a different spatial binning data_map = Map.create(map_type="wcs", width=(10, 5), binsz=1) coords = data_map.geom.get_coord() solid_angle = data_map.geom.solid_angle() vals = model(coords.lon, coords.lat) * solid_angle assert vals.unit == "" integral = vals.sum() assert_allclose(integral.value, 1, rtol=1e-4)
def test_boolean_arithmetics(): m_1 = Map.create(binsz=1, width=2) m_1.data = True m_2 = Map.create(binsz=1, width=2) m_2.data = False m_and = m_1 & m_2 assert not np.any(m_and.data) m_or = m_1 | m_2 assert np.all(m_or.data) m_not = ~m_2 assert np.all(m_not.data) m_xor = m_1 ^ m_1 assert not np.any(m_xor.data)
def test_interp_methods(): m = Map.create(npix=(3, 3)) m.data += np.arange(9).reshape((3, 3)) actual = m.interp_by_coord({"lon": 0.07, "lat": 0.03}, method="linear") assert_allclose(actual, 4.2) actual = m.interp_by_coord({"lon": 0.07, "lat": 0.03}, method="nearest") assert_allclose(actual, 3.)
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 exclusion_mask = Map.create( npix=(150, 150), binsz=0.05, skydir=skydir, proj="TAN", coordsys="GAL" ) mask = exclusion_mask.geom.region_mask([exclusion_region], inside=False) exclusion_mask.data = mask e_reco = MapAxis.from_bounds(0.1, 40, nbin=40, interp="log", unit="TeV").edges e_true = MapAxis.from_bounds(0.05, 100, nbin=200, interp="log", unit="TeV").edges dataset_maker = SpectrumDatasetMaker( region=on_region, e_reco=e_reco, e_true=e_true, containment_correction=True ) 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="" ) # Data preparation datasets = [] for ind, observation in enumerate(observations): dataset = dataset_maker.run(observation, selection=["counts", "aeff", "edisp"]) dataset_on_off = bkg_maker.run(dataset, observation) dataset_on_off = safe_mask_masker.run(dataset_on_off, observation) dataset_on_off.name = f"dataset{ind}" dataset_on_off.models = sky_model datasets.append(dataset_on_off) return Datasets(datasets)
def region_map(): axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=6, name="energy") m = Map.create( region="icrs;circle(83.63, 21.51, 1)", map_type="region", axes=[axis], unit="1/TeV", ) m.data = np.arange(m.data.size, dtype=float).reshape(m.geom.data_shape) return m
def test_map_quantity(map_type, unit): m = Map.create(binsz=0.1, width=10.0, map_type=map_type, unit=unit) # This is to test if default constructor with no unit performs as expected if unit is None: unit = "" assert m.quantity.unit == Unit(unit) m.quantity = Quantity(np.ones_like(m.data), "m2") assert m.unit == "m2"
def test_map_unit_read_write(map_type, unit): m = Map.create(binsz=0.1, width=10.0, map_type=map_type, unit=unit) hdu_list = m.to_hdulist(hdu="COUNTS") header = hdu_list["COUNTS"].header assert Unit(header["BUNIT"]) == Unit(unit) m2 = Map.from_hdulist(hdu_list) assert m2.unit == unit
def main(): data_store = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1") obs_id = data_store.obs_table["OBS_ID"] observations = data_store.get_observations(obs_id) m = Map.create() for obs in observations: log.info(f"Processing obs_id: {obs.obs_id}") m.fill_events(obs.events) m.write("survey_map.fits.gz")
def test_map_panel_plotter(): import matplotlib.pyplot as plt fig = plt.figure() plotter = MapPanelPlotter( figure=fig, xlim=Angle([-5, 5], "deg"), ylim=Angle([-2, 2], "deg"), npanels=2 ) map_image = Map.create(width=(180, 10), binsz=1) with mpl_plot_check(): plotter.plot(map_image)
def test_map_get_image_by_pix(binsz, width, map_type, skydir, axes, unit): m = Map.create( binsz=binsz, width=width, map_type=map_type, skydir=skydir, axes=axes, unit=unit ) pix = (1.2345, 0.1234)[: len(m.geom.axes)] m_image = m.get_image_by_pix(pix) im_geom = m.geom.to_image() idx = im_geom.get_idx() m_vals = m.get_by_pix(idx + pix) assert_equal(m_image.data, m_vals)
def images(): """A simple test case for the algorithm.""" counts = Map.create(npix=10, binsz=1) counts.data += 42 counts.data[4][4] = 1000 background = Map.from_geom(counts.geom) background.data += 42 exclusion = Map.from_geom(counts.geom) exclusion.data += 1 return {"counts": counts, "background": background, "exclusion": exclusion}
def test_arithmetics_after_serialization(tmp_path, interp): axis = MapAxis.from_bounds( 1.0, 10.0, 3, interp=interp, name="energy", node_type="center", unit="TeV" ) m_wcs = Map.create(binsz=0.1, width=1.0, map_type="wcs", skydir=(0, 0), axes=[axis]) m_wcs += 1 m_wcs.write(tmp_path / "tmp.fits") m_wcs_serialized = Map.read(tmp_path / "tmp.fits") m_wcs += m_wcs_serialized assert_allclose(m_wcs.data, 2.0)
def test_map_get_image_by_coord(binsz, width, map_type, skydir, axes, unit): m = Map.create( binsz=binsz, width=width, map_type=map_type, skydir=skydir, axes=axes, unit=unit ) m.data = np.arange(m.data.size, dtype=float).reshape(m.data.shape) coords = (3.456, 0.1234)[: len(m.geom.axes)] m_image = m.get_image_by_coord(coords) im_geom = m.geom.to_image() skycoord = im_geom.get_coord().skycoord m_vals = m.get_by_coord((skycoord,) + coords) assert_equal(m_image.data, m_vals)
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 exclusion_mask = Map.create(npix=(150, 150), binsz=0.05, skydir=skydir, proj="TAN", coordsys="GAL") mask = exclusion_mask.geom.region_mask([exclusion_region], inside=False) exclusion_mask.data = mask e_reco = MapAxis.from_bounds(0.1, 40, nbin=40, interp="log", unit="TeV").edges e_true = MapAxis.from_bounds(0.05, 100, nbin=200, interp="log", unit="TeV").edges stacked = SpectrumDatasetOnOff.create(e_reco=e_reco, e_true=e_true) stacked.name = "stacked" dataset_maker = SpectrumDatasetMaker(region=on_region, e_reco=e_reco, e_true=e_true, containment_correction=False) bkg_maker = ReflectedRegionsBackgroundMaker(exclusion_mask=exclusion_mask) safe_mask_masker = SafeMaskMaker(methods=["aeff-max"], aeff_percent=10) for observation in observations: dataset = dataset_maker.run(observation, selection=["counts", "aeff", "edisp"]) dataset_on_off = bkg_maker.run(dataset, observation) dataset_on_off = safe_mask_masker.run(dataset_on_off, observation) stacked.stack(dataset_on_off) return stacked
def test_read_write(tmp_path, node_type, interp): # Regression test for MapAxis interp and node_type FITS serialization # https://github.com/gammapy/gammapy/issues/1887 e_ax = MapAxis([1, 2], interp, "energy", node_type, "TeV") t_ax = MapAxis([3, 4], interp, "time", node_type, "s") m = Map.create(binsz=1, npix=10, axes=[e_ax, t_ax], unit="m2") # Check what Gammapy writes in the FITS header header = m.make_hdu().header assert header["INTERP1"] == interp assert header["INTERP2"] == interp # Check that all MapAxis properties are preserved on FITS I/O m.write(tmp_path / "tmp.fits", overwrite=True) m2 = Map.read(tmp_path / "tmp.fits") assert m2.geom == m.geom
def test_map_properties(): # Test default values and types of all map properties, # as well as the behaviour for the property get and set. m = Map.create(npix=(2, 1)) assert isinstance(m.geom, WcsGeom) m.geom = m.geom assert isinstance(m.geom, WcsGeom) assert isinstance(m.unit, u.CompositeUnit) assert m.unit == "" m.unit = "cm-2 s-1" assert m.unit.to_string() == "1 / (cm2 s)" assert isinstance(m.meta, OrderedDict) m.meta = {"spam": 42} assert isinstance(m.meta, OrderedDict) # The rest of the tests are for the `data` property assert isinstance(m.data, np.ndarray) assert m.data.dtype == np.float32 assert m.data.shape == (1, 2) assert_equal(m.data, 0) # Assigning an array of matching shape stores it away data = np.ones((1, 2)) m.data = data assert m.data is data # In-place modification += should work as expected m.data = np.array([[42, 43]]) data = m.data m.data += 1 assert m.data is data assert_equal(m.data, [[43, 44]]) # Assigning to a slice of the map data should work as expected data = m.data m.data[:, :1] = 99 assert m.data is data assert_equal(m.data, [[99, 44]]) # Assigning something that doesn't match raises an appropriate error with pytest.raises(ValueError): m.data = np.ones((1, 3))
def test_flat_map(self): """Test a simple example""" axis1 = MapAxis.from_edges([1, 2], name="axis1") axis2 = MapAxis.from_edges([9, 10], name="axis2") image = Map.create(npix=(10, 5), unit="s", axes=[axis1, axis2]) image.data[..., 3, 3] = 11 image.data[..., 3, 4] = 10 image.data[..., 3, 5] = 12 image.data[..., 3, 6] = np.nan image.data[..., 0, 9] = 1e20 table = find_peaks(image, threshold=3) row = table[0] assert len(table) == 3 assert_allclose(row["value"], 1e20) assert_allclose(row["ra"], 359.55) assert_allclose(row["dec"], -0.2)
def test_exclusion_region(tmp_path): config = get_example_config("1d") analysis = Analysis(config) exclusion_region = CircleSkyRegion(center=SkyCoord("85d 23d"), radius=1 * u.deg) exclusion_mask = Map.create(npix=(150, 150), binsz=0.05, skydir=SkyCoord("83d 22d")) mask = exclusion_mask.geom.region_mask([exclusion_region], inside=False) exclusion_mask.data = mask.astype(int) filename = tmp_path / "exclusion.fits" exclusion_mask.write(filename) config.datasets.background.exclusion = filename analysis.get_observations() analysis.get_datasets() assert len(analysis.datasets) == 2
def test_map_meta_read_write(map_type): meta = {"user": "******"} m = Map.create( binsz=0.1, width=10.0, map_type=map_type, skydir=SkyCoord(0.0, 30.0, unit="deg"), meta=meta, ) hdulist = m.to_hdulist(hdu="COUNTS") header = hdulist["COUNTS"].header assert header["META"] == '{"user": "******"}' m2 = Map.from_hdulist(hdulist) assert m2.meta == meta
def test_map_plot_mask(): from regions import CircleSkyRegion skydir = SkyCoord(0, 0, frame='galactic', unit='deg') m_wcs = Map.create( map_type='wcs', binsz=0.02, skydir=skydir, width=2.0, ) exclusion_region = CircleSkyRegion(center=SkyCoord(0.0, 0.0, unit="deg", frame="galactic"), radius=0.6 * u.deg) mask = ~m_wcs.geom.region_mask([exclusion_region]) with mpl_plot_check(): mask.plot_mask()
def test_map_copy(binsz, width, map_type, skydir, axes, unit): m = Map.create( binsz=binsz, width=width, map_type=map_type, skydir=skydir, axes=axes, unit=unit ) m_copy = m.copy() assert repr(m) == repr(m_copy) m_copy = m.copy(unit="cm-2 s-1") assert m_copy.unit == "cm-2 s-1" assert m_copy.unit is not m.unit m_copy = m.copy(meta={"is_copy": True}) assert m_copy.meta["is_copy"] assert m_copy.meta is not m.meta m_copy = m.copy(data=42 * np.ones(m.data.shape)) assert m_copy.data[(0,) * m_copy.data.ndim] == 42 assert m_copy.data is not m.data