def test_psf_map_write_gtpsf(tmpdir): energy_axis_true = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=3, name="energy_true") geom = RegionGeom.create("icrs;circle(0, 0, 0.1)") psf = PSFMap.from_gauss(energy_axis_true=energy_axis_true, sigma=[0.1, 0.2, 0.3] * u.deg, geom=geom) psf.exposure_map = Map.from_geom(geom.to_cube([energy_axis_true]), unit="cm2 s") filename = tmpdir / "test_psf.fits" psf.write(filename, format="gtpsf") psf = PSFMap.read(filename, format="gtpsf") value = psf.containment_radius(energy_true=energy_axis_true.center, fraction=0.394) assert_allclose(value, [0.1, 0.2, 0.3] * u.deg, rtol=1e-5) assert psf.psf_map.unit == "sr-1"
def test_integrate_geom(): model = GaussianSpatialModel(lon="0d", lat="0d", sigma=0.1 * u.deg, frame='icrs') spectral_model = PowerLawSpectralModel(amplitude="1e-11 cm-2 s-1 TeV-1") sky_model = SkyModel(spectral_model=spectral_model, spatial_model=model) center = SkyCoord("0d", "0d", frame='icrs') radius = 0.3 * u.deg square = CircleSkyRegion(center, radius) axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=3, name='energy_true') geom = RegionGeom(region=square, axes=[axis], binsz_wcs="0.01deg") integral = sky_model.integrate_geom(geom).data assert_allclose(integral / 1e-12, [[[5.299]], [[2.460]], [[1.142]]], rtol=1e-3)
def test_npred_models(): e_reco = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=3) geom = RegionGeom(region=None, axes=[e_reco]) spectrum_dataset = SpectrumDataset.create(geom=geom) spectrum_dataset.exposure.quantity = 1e10 * u.Unit("cm2 h") pwl_1 = PowerLawSpectralModel(index=2) pwl_2 = PowerLawSpectralModel(index=2) model_1 = SkyModel(spectral_model=pwl_1) model_2 = SkyModel(spectral_model=pwl_2) spectrum_dataset.models = Models([model_1, model_2]) npred = spectrum_dataset.npred() assert_allclose(npred.data.sum(), 64.8) npred_sig = spectrum_dataset.npred_signal() assert_allclose(npred_sig.data.sum(), 64.8) npred_sig_model1 = spectrum_dataset.npred_signal(model_name=model_1.name) assert_allclose(npred_sig_model1.data.sum(), 32.4)
def test_edispkernel_from_1d(): energy_axis_true = MapAxis.from_energy_bounds("0.5 TeV", "5 TeV", nbin=31, name="energy_true") energy_axis = MapAxis.from_energy_bounds("0.1 TeV", "10 TeV", nbin=11, name="energy") edisp = EDispKernel.from_gauss(energy_axis_true, energy_axis, 0.1, 0.0) geom = RegionGeom.create("fk5;circle(0.,0., 10.") region_edisp = EDispKernelMap.from_edisp_kernel(edisp, geom=geom) sum_kernel = np.sum(region_edisp.edisp_map.data[..., 0, 0], axis=1) assert_allclose(sum_kernel, 1, rtol=1e-5) allsky_edisp = EDispKernelMap.from_edisp_kernel(edisp) sum_kernel = np.sum(allsky_edisp.edisp_map.data[..., 0, 0], axis=1) assert allsky_edisp.edisp_map.data.shape == (31, 11, 1, 2) assert_allclose(sum_kernel, 1, rtol=1e-5)
def get_spectrumdataset(name): 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) energy_axis = MapAxis.from_energy_bounds(0.1, 40, nbin=15, per_decade=True, unit="TeV", name="energy") energy_axis_true = MapAxis.from_energy_bounds(0.05, 100, nbin=20, per_decade=True, unit="TeV", name="energy_true") geom = RegionGeom.create(region=on_region, axes=[energy_axis]) return SpectrumDataset.create(geom=geom, energy_axis_true=energy_axis_true, name=name)
def test_reflected_bkg_maker_no_off_background(reflected_bkg_maker, observations): pos = SkyCoord(83.6333313, 21.51444435, unit="deg", frame="icrs") radius = Angle(0.11, "deg") region = CircleSkyRegion(pos, radius) maker = SpectrumDatasetMaker(selection=["counts", "background"]) datasets = [] e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") e_true = MapAxis.from_edges(np.logspace(-0.5, 2, 11) * u.TeV, name="energy_true") geom = RegionGeom.create(region=region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom, energy_axis_true=e_true) for obs in observations: dataset = maker.run(dataset_empty, obs) dataset_on_off = reflected_bkg_maker.run(dataset, obs) datasets.append(dataset_on_off) assert_allclose(datasets[0].counts_off.data, 0) assert_allclose(datasets[0].acceptance_off, 0)
def get_spectrumdataset_rad_max(name): """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(0.005, 50, nbin=28, per_decade=False, unit="TeV", name="energy") energy_axis_true = MapAxis.from_energy_bounds(0.005, 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 test_reflected_bkg_maker_no_off(reflected_bkg_maker, observations, caplog): pos = SkyCoord(83.6333313, 21.51444435, unit="deg", frame="icrs") radius = Angle(0.11, "deg") region = CircleSkyRegion(pos, radius) maker = SpectrumDatasetMaker(selection=["counts", "exposure"]) datasets = [] e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") e_true = MapAxis.from_edges(np.logspace(-0.5, 2, 11) * u.TeV, name="energy_true") geom = RegionGeom.create(region=region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom, energy_axis_true=e_true) safe_mask_masker = SafeMaskMaker(methods=["aeff-max"], aeff_percent=10) for obs in observations: dataset = maker.run(dataset_empty, obs) dataset_on_off = reflected_bkg_maker.run(dataset, obs) dataset_on_off = safe_mask_masker.run(dataset_on_off, obs) datasets.append(dataset_on_off) assert datasets[0].counts_off is None assert_allclose(datasets[0].acceptance_off, 0) assert_allclose(datasets[0].mask_safe.data, False) assert "WARNING" in [record.levelname for record in caplog.records] message1 = ( f"ReflectedRegionsBackgroundMaker failed. " f"No OFF region found outside exclusion mask for dataset '{datasets[0].name}'." ) message2 = (f"ReflectedRegionsBackgroundMaker failed. " f"Setting {datasets[0].name} mask to False.") assert message1 in [record.message for record in caplog.records] assert message2 in [record.message for record in caplog.records]
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 make_counts_off(self, dataset, observation): """Make off counts. Parameters ---------- dataset : `SpectrumDataset` Spectrum dataset. observation : `DatastoreObservation` Data store observation. Returns ------- counts_off : `RegionNDMap` Off counts. """ finder = self._get_finder(dataset, observation) finder.run() energy_axis = dataset.counts.geom.axes["energy"] if len(finder.reflected_regions) > 0: region_union = list_to_compound_region(finder.reflected_regions) wcs = finder.reference_map.geom.wcs geom = RegionGeom.create(region=region_union, axes=[energy_axis], wcs=wcs) counts_off = RegionNDMap.from_geom(geom=geom) counts_off.fill_events(observation.events) acceptance_off = len(finder.reflected_regions) else: # if no OFF regions are found, off is set to None and acceptance_off to zero log.warning( f"ReflectedRegionsBackgroundMaker failed. No OFF region found outside exclusion mask for {dataset.name}." ) counts_off = None acceptance_off = 0 return counts_off, acceptance_off
def test_spectrum_dataset_maker_hess_dl3(spectrum_dataset_crab, observations_hess_dl3): datasets = [] maker = SpectrumDatasetMaker(use_region_center=False) datasets = [] for obs in observations_hess_dl3: dataset = maker.run(spectrum_dataset_crab, obs) datasets.append(dataset) # Exposure assert_allclose(datasets[0].exposure.data.sum(), 7374718644.757894) assert_allclose(datasets[1].exposure.data.sum(), 6691006466.659032) # Background assert_allclose(datasets[0].npred_background().data.sum(), 7.7429157, rtol=1e-5) assert_allclose(datasets[1].npred_background().data.sum(), 5.7314076, rtol=1e-5) # Compare background with using bigger region e_reco = datasets[0].background.geom.axes['energy'] e_true = datasets[0].exposure.geom.axes['energy_true'] geom_bigger = RegionGeom.create("icrs;circle(83.63, 22.01, 0.22)", axes=[e_reco]) datasets_big_region = [] bigger_region_dataset = SpectrumDataset.create(geom=geom_bigger, energy_axis_true=e_true) for obs in observations_hess_dl3: dataset = maker.run(bigger_region_dataset, obs) datasets_big_region.append(dataset) ratio_regions = datasets[0].counts.geom.solid_angle()/datasets_big_region[1].counts.geom.solid_angle() ratio_bg_1 = datasets[0].npred_background().data.sum()/ datasets_big_region[0].npred_background().data.sum() ratio_bg_2 = datasets[1].npred_background().data.sum()/ datasets_big_region[1].npred_background().data.sum() assert_allclose(ratio_bg_1, ratio_regions, rtol=1e-2) assert_allclose(ratio_bg_2, ratio_regions, rtol=1e-2) #Edisp -> it isn't exactly 8, is that right? it also isn't without averaging assert_allclose(datasets[0].edisp.edisp_map.data[:,:,0,0].sum(), e_reco.nbin*2, rtol=1e-1) assert_allclose(datasets[1].edisp.edisp_map.data[:,:,0,0].sum(), e_reco.nbin*2, rtol=1e-1)
def test_run(observations, phase_bkg_maker): maker = SpectrumDatasetMaker() e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") e_true = MapAxis.from_edges(np.logspace(-0.5, 2, 11) * u.TeV, name="energy_true") pos = SkyCoord("08h35m20.65525s", "-45d10m35.1545s", frame="icrs") radius = Angle(0.2, "deg") region = SphericalCircleSkyRegion(pos, radius) geom = RegionGeom.create(region=region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom, energy_axis_true=e_true) obs = observations["111630"] dataset = maker.run(dataset_empty, obs) dataset_on_off = phase_bkg_maker.run(dataset, obs) assert_allclose(dataset_on_off.acceptance, 0.1) assert_allclose(dataset_on_off.acceptance_off, 0.3) assert_allclose(dataset_on_off.counts.data.sum(), 28) assert_allclose(dataset_on_off.counts_off.data.sum(), 57)
def test_reflected_bkg_maker(on_region, reflected_bkg_maker, observations): datasets = [] e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") e_true = MapAxis.from_edges(np.logspace(-0.5, 2, 11) * u.TeV, name="energy_true") geom = RegionGeom(region=on_region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom, energy_axis_true=e_true) maker = SpectrumDatasetMaker(selection=["counts"]) for obs in observations: dataset = maker.run(dataset_empty, obs) dataset_on_off = reflected_bkg_maker.run(dataset, obs) datasets.append(dataset_on_off) assert_allclose(datasets[0].counts_off.data.sum(), 76) assert_allclose(datasets[1].counts_off.data.sum(), 60) regions_0 = compound_region_to_list(datasets[0].counts_off.geom.region) regions_1 = compound_region_to_list(datasets[1].counts_off.geom.region) assert_allclose(len(regions_0), 11) assert_allclose(len(regions_1), 11)
def test_to_wcs_geom(region): geom = RegionGeom(region) wcs_geom = geom.to_wcs_geom() assert_allclose(wcs_geom.center_coord[1].value, 0, rtol=0.001, atol=0) assert_allclose(wcs_geom.width[0], 360 * u.deg, rtol=1, atol=0) assert wcs_geom.wcs.wcs.ctype[1] == 'GLAT-TAN' # test with an extra axis axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=10) geom_cube = geom.to_cube([axis]) wcs_geom_cube = geom_cube.to_wcs_geom() assert wcs_geom_cube.to_image() == wcs_geom assert wcs_geom_cube.axes[0] == axis # test with minimum widths width_min = 3 * u.deg wcs_geom = geom.to_wcs_geom(width_min=width_min) assert_allclose(wcs_geom.center_coord[1].value, 0, rtol=0.001, atol=0) assert_allclose(wcs_geom.width, [[3], [3]] * u.deg, rtol=1, atol=0) width_min = [1, 3] * u.deg wcs_geom = geom.to_wcs_geom(width_min=width_min) assert_allclose(wcs_geom.center_coord[1].value, 0, rtol=0.001, atol=0) assert_allclose(wcs_geom.width, [[2], [3]] * u.deg, rtol=1, atol=0)
offset_axis=offset_axis, migra_axis=MIGRA_AXIS_DEFAULT, bias=0, sigma=0.2, ) observation = Observation.create( obs_id=0, pointing=SkyCoord("0d", "0d", frame="icrs"), irfs={"aeff": aeff, "edisp": edisp}, tstart=0 * u.h, tstop=0.5 * u.h, location=observatory_locations["hess"], ) geom = RegionGeom.create("icrs;circle(0, 0, 0.1)", axes=[energy_reco]) stacked = SpectrumDataset.create(geom=geom, energy_axis_true=energy_true) maker = SpectrumDatasetMaker(selection=["edisp", "exposure"]) dataset_1 = maker.run(stacked.copy(), observation=observation) dataset_2 = maker.run(stacked.copy(), observation=observation) pwl = PowerLawSpectralModel() model = SkyModel(spectral_model=pwl, name="test-source") dataset_1.mask_safe = geom.energy_mask(energy_min=2 * u.TeV) dataset_2.mask_safe = geom.energy_mask(energy_min=0.6 * u.TeV) dataset_1.models = model
def _spectrum_extraction(self): """Run all steps for the spectrum extraction.""" log.info("Reducing spectrum datasets.") datasets_settings = self.config.datasets on_lon = datasets_settings.on_region.lon on_lat = datasets_settings.on_region.lat on_center = SkyCoord(on_lon, on_lat, frame=datasets_settings.on_region.frame) on_region = CircleSkyRegion(on_center, datasets_settings.on_region.radius) maker_config = {} if datasets_settings.containment_correction: maker_config[ "containment_correction"] = datasets_settings.containment_correction e_reco = self._make_energy_axis(datasets_settings.geom.axes.energy) maker_config["selection"] = ["counts", "exposure", "edisp"] dataset_maker = SpectrumDatasetMaker(**maker_config) bkg_maker_config = {} if datasets_settings.background.exclusion: exclusion_region = Map.read(datasets_settings.background.exclusion) bkg_maker_config["exclusion_mask"] = exclusion_region bkg_maker_config.update(datasets_settings.background.parameters) bkg_method = datasets_settings.background.method if bkg_method == "reflected": bkg_maker = ReflectedRegionsBackgroundMaker(**bkg_maker_config) log.debug( f"Creating ReflectedRegionsBackgroundMaker with arguments {bkg_maker_config}" ) else: bkg_maker = None log.warning( f"No background maker set for 1d analysis. Check configuration." ) safe_mask_selection = datasets_settings.safe_mask.methods safe_mask_settings = datasets_settings.safe_mask.parameters safe_mask_maker = SafeMaskMaker(methods=safe_mask_selection, **safe_mask_settings) e_true = self._make_energy_axis( datasets_settings.geom.axes.energy_true, name="energy_true") geom = RegionGeom.create(region=on_region, axes=[e_reco]) reference = SpectrumDataset.create(geom=geom, energy_axis_true=e_true) datasets = [] for obs in self.observations: log.info(f"Processing observation {obs.obs_id}") dataset = dataset_maker.run(reference.copy(), obs) if bkg_maker is not None: dataset = bkg_maker.run(dataset, obs) if dataset.counts_off is None: log.info( f"No OFF region found for observation {obs.obs_id}. Discarding." ) continue dataset = safe_mask_maker.run(dataset, obs) log.debug(dataset) datasets.append(dataset) self.datasets = Datasets(datasets) if datasets_settings.stack: stacked = self.datasets.stack_reduce(name="stacked") self.datasets = Datasets([stacked])
def spectrum_dataset_crab_fine(): e_true = MapAxis.from_edges(np.logspace(-2, 2.5, 109) * u.TeV, name="energy_true") e_reco = MapAxis.from_energy_edges(np.logspace(-2, 2, 73) * u.TeV) geom = RegionGeom.create("icrs;circle(83.63, 22.01, 0.11)", axes=[e_reco]) return SpectrumDataset.create(geom=geom, energy_axis_true=e_true)
def spectrum_dataset_gc(): e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") e_true = MapAxis.from_edges(np.logspace(-1, 2, 13) * u.TeV, name="energy_true") geom = RegionGeom.create("galactic;circle(0, 0, 0.11)", axes=[e_reco]) return SpectrumDataset.create(geom=geom, energy_axis_true=e_true)
def test_width(region): geom = RegionGeom.create(region) assert_allclose(geom.width.value, [2.02, 2.02])
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]) empty = SpectrumDatasetOnOff.create(geom, energy_axis_true=e_true) dataset_maker = SpectrumDatasetMaker( containment_correction=True, 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="") # Data preparation datasets = [] for idx, observation in enumerate(observations): dataset = empty.copy(name=f"dataset{idx}") 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) dataset_on_off.models = sky_model datasets.append(dataset_on_off) return Datasets(datasets)
def test_contains(region): geom = RegionGeom.create(region) position = SkyCoord([0, 0], [0, 1.1], frame="galactic", unit="deg") contains = geom.contains(coords={"skycoord": position}) assert_allclose(contains, [1, 0])
def test_repr(region): axis = MapAxis.from_edges([1, 3.162278, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) assert "RegionGeom" in repr(geom) assert "CircleSkyRegion" in repr(geom)
def make_counts_off(self, dataset, observation): """Make off counts. **NOTE for 1D analysis:** as for `~gammapy.makers.map.MapDatasetMaker.make_counts`, if the geometry of the dataset is a `~regions.CircleSkyRegion` then only a single instance of the `ReflectedRegionsFinder` will be called. If, on the other hand, the geometry of the dataset is a `~regions.PointSkyRegion`, then we have to call the `ReflectedRegionsFinder` several time, each time with a different size of the on region that we will read from the `RAD_MAX_2D` table. Parameters ---------- dataset : `~gammapy.datasets.SpectrumDataset` Spectrum dataset. observation : `~gammapy.observation.Observation` Observation container. Returns ------- counts_off : `~gammapy.maps.RegionNDMap` Counts vs estimated energy extracted from the OFF regions. """ on_geom = dataset.counts.geom if observation.rad_max is not None: if not isinstance(on_geom.region, PointSkyRegion): raise ValueError( 'Must use PointSkyRegion on region in point-like analysis') counts_off, acceptance_off = make_counts_off_rad_max( on_geom=on_geom, rad_max=observation.rad_max, events=observation.events, region_finder=self.region_finder, exclusion_mask=self.exclusion_mask, ) else: regions, wcs = self.region_finder.run( center=observation.pointing_radec, region=on_geom.region, exclusion_mask=self.exclusion_mask, ) energy_axis = on_geom.axes["energy"] if len(regions) > 0: off_geom = RegionGeom.from_regions( regions=regions, axes=[energy_axis], wcs=wcs, ) counts_off = RegionNDMap.from_geom(geom=off_geom) counts_off.fill_events(observation.events) acceptance_off = RegionNDMap.from_geom(geom=off_geom, data=len(regions)) else: # if no OFF regions are found, off is set to None and acceptance_off to zero log.warning( f"ReflectedRegionsBackgroundMaker failed. No OFF region found outside exclusion mask for {dataset.name}." ) counts_off = None acceptance_off = RegionNDMap.from_geom(geom=on_geom, data=0) return counts_off, acceptance_off
# Default plotting settings #circle.plot_region() # Different line styles, widths and colors #box.plot_region(lw=2, linestyle='--', ec='k') #ellipse.plot_region(lw=2, linestyle=':', ec='white') # Filling the region with a color #annulus.plot_region(lw=2, ec='purple', fc='purple') #Galactic_Center = SkyCoord('17:45:40.04', '−29:00:28.1', frame="icrs", unit=(u.hourangle, u.deg)) Galactic_Center = SkyCoord(0.0, 0.0, frame="galactic", unit=(u.deg, u.deg)) m = Map.create(binsz=2.0, width=(180.0, 24.0*15.0), skydir=Galactic_Center, frame="galactic", proj="TAN") #m.data.fill(0.0) m.plot(add_cbar=True) plane_survey_region = RectangleSkyRegion(center=SkyCoord(0.0,0.0, frame='galactic', unit=(u.deg, u.deg)), width=(2.0*85.0) * u.deg, height=20 * u.deg, angle=0.0*u.deg) LMC_region = RectangleSkyRegion(center=SkyCoord(280.4652, -32.8884, frame='galactic', unit=(u.deg, u.deg)), width=(322.827/60) * u.deg, height=(274.770/60) * u.deg, angle=0.0*u.deg) SMC_region = plane_survey_box = RegionGeom.create(plane_survey_region) LMC_box = RegionGeom.create(LMC_region) plane_survey_box.plot_region(lw=2, ec='purple', fc='purple', alpha=0.2) LMC_box.plot_region(lw=2, ec='purple', fc='purple') plt.show()
obs_ids = data_store.obs_table["OBS_ID"][mask].data observations = data_store.get_observations(obs_ids) crab_position = SkyCoord(83.63, 22.01, unit="deg", frame="icrs") # The ON region center is defined in the icrs frame. The angle is defined w.r.t. to its axis. rectangle = RectangleSkyRegion(center=crab_position, width=0.5 * u.deg, height=0.4 * u.deg, angle=0 * u.deg) bkg_maker = ReflectedRegionsBackgroundMaker(min_distance=0.1 * u.rad) dataset_maker = SpectrumDatasetMaker(selection=["counts"]) energy_axis = MapAxis.from_energy_bounds(0.1, 100, 30, unit="TeV") geom = RegionGeom.create(region=rectangle, axes=[energy_axis]) dataset_empty = SpectrumDataset.create(geom=geom) datasets = [] for obs in observations: dataset = dataset_maker.run(dataset_empty.copy(name=f"obs-{obs.obs_id}"), obs) dataset_on_off = bkg_maker.run(observation=obs, dataset=dataset) datasets.append(dataset_on_off) m = Map.create(skydir=crab_position, width=(8, 8), proj="TAN") ax = m.plot(vmin=-1, vmax=0)
def test_create(region): geom = RegionGeom.create(region) assert geom.frame == "galactic" assert geom.projection == "TAN" assert not geom.is_image assert not geom.is_allsky
def make_counts_off_rad_max( on_geom, rad_max, events, region_finder, exclusion_mask=None, ): """Extract the OFF counts and the ON / OFF acceptance considering for the sizes of the ON and OFF regions the values in the `RAD_MAX_2D` table. Per each estimated energy bin a `ReflectedRegionsFinder` is defined to search for the OFF regions. Parameters ---------- geom: `~gammapy.maps.RegionGeom` reference map geom for the on region rad_max: `~gammapy.irf.RadMax2D` the RAD_MAX_2D table IRF events: `~gammapy.data.EventList` event list to be used to compute the OFF counts region_finder: `~gammapy.makers.background.reflected.RegionFinder` Returns ------- counts_off : `~gammapy.maps.RegionNDMap` OFF Counts vs estimated energy extracted from the ON region. acceptance_off : `~gammapy.maps.RegionNDMap` ratio of the acceptances of the OFF to ON regions. """ off_regions, wcs = region_finder.run( center=events.pointing_radec, region=on_geom.region, exclusion_mask=exclusion_mask, ) if len(off_regions) == 0: log.warning("RegionsFinder returned no regions") # counts_off=None, acceptance_off=0 return None, RegionNDMap.from_geom(on_geom, data=0) # check for overlap energy_axis = on_geom.axes["energy"] offset = on_geom.region.center.separation(events.pointing_radec) e_min, e_max = energy_axis.edges[[0, -1]] regions = [on_geom.region] + off_regions if are_regions_overlapping_rad_max(regions, rad_max, offset, e_min, e_max): log.warning("Found overlapping on/off regions, choose less off regions") # counts_off=None, acceptance_off=0 return None, RegionNDMap.from_geom(on_geom, data=0) off_region_geom = RegionGeom.from_regions( regions=off_regions, axes=[energy_axis], wcs=wcs, ) counts_off = RegionNDMap.from_geom(geom=off_region_geom) acceptance_off = RegionNDMap.from_geom( geom=off_region_geom, data=np.full(energy_axis.nbin, len(off_regions)) ) for off_region in off_regions: selected_events = events.select_rad_max( rad_max=rad_max, position=off_region.center ) counts_off.fill_events(selected_events) return counts_off, acceptance_off
def plot_regions(ax, regions, on_region, exclusion_mask): """Little helper function to plot off regions""" exclusion_mask.plot_mask(ax=ax, colors="gray") on_region.to_pixel(ax.wcs).plot(ax=ax, edgecolor="tab:orange") geom = RegionGeom.from_regions(regions) geom.plot_region(ax=ax, color="tab:blue")
def make_observation_list(): """obs with dummy IRF""" nbin = 3 energy = np.logspace(-1, 1, nbin + 1) * u.TeV livetime = 2 * u.h data_on = np.arange(nbin) dataoff_1 = np.ones(3) dataoff_2 = np.ones(3) * 3 dataoff_1[1] = 0 dataoff_2[1] = 0 axis = MapAxis.from_edges(energy, name="energy", interp="log") axis_true = axis.copy(name="energy_true") geom = RegionGeom(region=None, axes=[axis]) geom_true = RegionGeom(region=None, axes=[axis_true]) on_vector = RegionNDMap.from_geom(geom=geom, data=data_on) off_vector1 = RegionNDMap.from_geom(geom=geom, data=dataoff_1) off_vector2 = RegionNDMap.from_geom(geom=geom, data=dataoff_2) mask_safe = RegionNDMap.from_geom(geom, dtype=bool) mask_safe.data += True acceptance = RegionNDMap.from_geom(geom=geom, data=1) acceptance_off_1 = RegionNDMap.from_geom(geom=geom, data=2) acceptance_off_2 = RegionNDMap.from_geom(geom=geom, data=4) aeff = RegionNDMap.from_geom(geom_true, data=1, unit="m2") edisp = EDispKernelMap.from_gauss(energy_axis=axis, energy_axis_true=axis_true, sigma=0.2, bias=0, geom=geom) time_ref = Time("2010-01-01") gti1 = make_gti({ "START": [5, 6, 1, 2], "STOP": [8, 7, 3, 4] }, time_ref=time_ref) gti2 = make_gti({"START": [14], "STOP": [15]}, time_ref=time_ref) exposure = aeff * livetime exposure.meta["livetime"] = livetime obs1 = SpectrumDatasetOnOff( counts=on_vector, counts_off=off_vector1, exposure=exposure, edisp=edisp, mask_safe=mask_safe, acceptance=acceptance.copy(), acceptance_off=acceptance_off_1, name="1", gti=gti1, ) obs2 = SpectrumDatasetOnOff( counts=on_vector, counts_off=off_vector2, exposure=exposure.copy(), edisp=edisp, mask_safe=mask_safe, acceptance=acceptance.copy(), acceptance_off=acceptance_off_2, name="2", gti=gti2, ) obs_list = [obs1, obs2] return obs_list
def test_downsample(region): axis = MapAxis.from_edges([1, 3.162278, 10] * u.TeV, name="energy", interp="log") geom = RegionGeom.create(region, axes=[axis]) geom_down = geom.downsample(factor=2, axis_name="energy") assert_allclose(geom_down.axes[0].edges.value, [1.0, 10.0], rtol=1e-5)