def create_datasets_1d(observations, target_position): on_region_radius = Angle("0.11 deg") on_region = CircleSkyRegion(center=target_position, radius=on_region_radius) # Target geometry definition e_reco = MapAxis.from_energy_bounds(0.23, 20, 12, "TeV") e_true = MapAxis.from_energy_bounds(0.1, 40, 40, "TeV", name="energy_true") #data reduction makers dataset_maker = SpectrumDatasetMaker( containment_correction=True, selection=["counts", "exposure", "edisp"]) bkg_maker = ReflectedRegionsBackgroundMaker() safe_mask_maker = SafeMaskMaker(methods=["aeff-max"], aeff_percent=10) datasets = [] geom = RegionGeom(on_region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom, energy_axis_true=e_true) for obs in observations: dataset = dataset_maker.run(dataset_empty.copy(), obs) dataset_on_off = bkg_maker.run(dataset, obs) if dataset_on_off.counts_off.data.sum() > 0: dataset_on_off = safe_mask_maker.run(dataset_on_off, obs) datasets.append(dataset_on_off) return datasets
def test_dataset_maker_spectrum_rad_max(observations_magic_rad_max): """test the energy-dependent spectrum extraction""" observation = observations_magic_rad_max[0] maker = SpectrumDatasetMaker( containment_correction=False, selection=["counts", "exposure", "edisp"] ) dataset = maker.run(get_spectrumdataset_rad_max("spec"), observation) finder = WobbleRegionsFinder(n_off_regions=1) bkg_maker = ReflectedRegionsBackgroundMaker(region_finder=finder) dataset_on_off = bkg_maker.run(dataset, observation) counts = dataset_on_off.counts counts_off = dataset_on_off.counts_off assert counts.unit == "" assert counts_off is not None, "Extracting off counts failed" assert counts_off.unit == "" assert_allclose(counts.data.sum(), 949, rtol=1e-5) assert_allclose(counts_off.data.sum(), 517, rtol=1e-5) exposure = dataset_on_off.exposure assert exposure.unit == "m2 s" assert_allclose(exposure.data.mean(), 67838458.245686, rtol=1e-5)
def test_reflected_bkg_maker_with_wobble_finder(on_region, observations, exclusion_mask): datasets = [] reflected_bkg_maker = ReflectedRegionsBackgroundMaker( region_finder=WobbleRegionsFinder(n_off_regions=3), exclusion_mask=exclusion_mask, ) e_reco = MapAxis.from_edges(np.logspace(0, 2, 5) * u.TeV, name="energy") geom = RegionGeom(region=on_region, axes=[e_reco]) dataset_empty = SpectrumDataset.create(geom=geom) spectrum_dataset_maker = SpectrumDatasetMaker(selection=["counts"]) for obs in observations: dataset = spectrum_dataset_maker.run(dataset_empty, obs) dataset_on_off = reflected_bkg_maker.run(dataset, obs) datasets.append(dataset_on_off) regions_0 = compound_region_to_regions(datasets[0].counts_off.geom.region) regions_1 = compound_region_to_regions(datasets[1].counts_off.geom.region) assert_allclose(len(regions_0), 3) assert_allclose(len(regions_1), 3)
def makers_spectrum(exclusion_mask): return [ SpectrumDatasetMaker(containment_correction=True, selection=["counts", "exposure", "edisp"]), ReflectedRegionsBackgroundMaker(exclusion_mask=exclusion_mask), SafeMaskMaker(methods=["aeff-max"], aeff_percent=10), ]
def _create_background_maker(self): """Create the Background maker.""" log.info("Creating the background Maker.") datasets_settings = self.config.datasets bkg_maker_config = {} if datasets_settings.background.exclusion: path = make_path(datasets_settings.background.exclusion) exclusion_mask = Map.read(path) exclusion_mask.data = exclusion_mask.data.astype(bool) bkg_maker_config["exclusion_mask"] = exclusion_mask bkg_maker_config.update(datasets_settings.background.parameters) bkg_method = datasets_settings.background.method bkg_maker = None if bkg_method == "fov_background": log.debug(f"Creating FoVBackgroundMaker with arguments {bkg_maker_config}") bkg_maker = FoVBackgroundMaker(**bkg_maker_config) elif bkg_method == "ring": bkg_maker = RingBackgroundMaker(**bkg_maker_config) log.debug(f"Creating RingBackgroundMaker with arguments {bkg_maker_config}") if datasets_settings.geom.axes.energy.nbins > 1: raise ValueError( "You need to define a single-bin energy geometry for your dataset." ) elif bkg_method == "reflected": bkg_maker = ReflectedRegionsBackgroundMaker(**bkg_maker_config) log.debug( f"Creating ReflectedRegionsBackgroundMaker with arguments {bkg_maker_config}" ) else: log.warning("No background maker set. Check configuration.") return bkg_maker
def reflected_regions_bkg_maker(): 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) exclusion_mask = geom.region_mask([exclusion_region], inside=False) return ReflectedRegionsBackgroundMaker(exclusion_mask=exclusion_mask, min_distance_input="0.2 deg")
def test_dataset_maker_spectrum_global_rad_max(): """test the energy-dependent spectrum extraction""" observation = Observation.read('$GAMMAPY_DATA/joint-crab/dl3/magic/run_05029748_DL3.fits') maker = SpectrumDatasetMaker( containment_correction=False, selection=["counts", "exposure", "edisp"] ) dataset = maker.run(get_spectrumdataset_rad_max("spec"), observation) finder = WobbleRegionsFinder(n_off_regions=3) bkg_maker = ReflectedRegionsBackgroundMaker(region_finder=finder) dataset_on_off = bkg_maker.run(dataset, observation) counts = dataset_on_off.counts counts_off = dataset_on_off.counts_off assert counts.unit == "" assert counts_off.unit == "" assert_allclose(counts.data.sum(), 437, rtol=1e-5) assert_allclose(counts_off.data.sum(), 273, rtol=1e-5)
def test_dataset_maker_spectrum_rad_max_all_excluded(observations_magic_rad_max, caplog): """test the energy-dependent spectrum extraction""" observation = observations_magic_rad_max[0] maker = SpectrumDatasetMaker( containment_correction=False, selection=["counts", "exposure", "edisp"] ) dataset = maker.run(get_spectrumdataset_rad_max("spec"), observation) # excludes all possible off regions exclusion_region = CircleSkyRegion( center=observation.pointing_radec, radius=1 * u.deg, ) geom = WcsGeom.create( npix=(150, 150), binsz=0.05, skydir=observation.pointing_radec, proj="TAN", frame="icrs" ) exclusion_mask = ~geom.region_mask([exclusion_region]) finder = WobbleRegionsFinder(n_off_regions=1) bkg_maker = ReflectedRegionsBackgroundMaker( region_finder=finder, exclusion_mask=exclusion_mask, ) with caplog.at_level(logging.WARNING): dataset_on_off = bkg_maker.run(dataset, observation) # overlapping off regions means not counts will be filled assert dataset_on_off.counts_off is None assert (dataset_on_off.acceptance_off.data == 0).all() assert len(caplog.record_tuples) == 2 assert caplog.record_tuples[0] == ( 'gammapy.makers.utils', logging.WARNING, "RegionsFinder returned no regions" )
def test_dataset_maker_spectrum_rad_max(observations_magic): """test the energy-dependent spectrum extraction""" observation = observations_magic[0] maker = SpectrumDatasetMaker(containment_correction=False, selection=["counts", "exposure", "edisp"]) dataset = maker.run(get_spectrumdataset_rad_max("spec"), observation) bkg_maker = ReflectedRegionsBackgroundMaker() dataset_on_off = bkg_maker.run(dataset, observation) counts = dataset_on_off.counts counts_off = dataset_on_off.counts_off assert counts.unit == "" assert counts_off.unit == "" assert_allclose(counts.data.sum(), 1138, rtol=1e-5) assert_allclose(counts_off.data.sum(), 2128, rtol=1e-5) exposure = dataset_on_off.exposure assert exposure.unit == "m2 s" assert_allclose(exposure.data.mean(), 68714990.52908568, rtol=1e-5)
def test_dataset_maker_spectrum_rad_max_overlapping(observations_magic_rad_max, caplog): """test the energy-dependent spectrum extraction""" observation = observations_magic_rad_max[0] maker = SpectrumDatasetMaker( containment_correction=False, selection=["counts", "exposure", "edisp"] ) finder = WobbleRegionsFinder(n_off_regions=5) bkg_maker = ReflectedRegionsBackgroundMaker(region_finder=finder) with caplog.at_level(logging.WARNING): dataset = maker.run(get_spectrumdataset_rad_max("spec"), observation) dataset_on_off = bkg_maker.run(dataset, observation) assert len(caplog.record_tuples) == 2 assert caplog.record_tuples[0] == ( 'gammapy.makers.utils', logging.WARNING, 'Found overlapping on/off regions, choose less off regions' ) # overlapping off regions means not counts will be filled assert dataset_on_off.counts_off is None assert (dataset_on_off.acceptance_off.data == 0).all() # test that it works if we only look at higher energies with lower # rad max, allowing more off regions caplog.clear() with caplog.at_level(logging.WARNING): dataset = maker.run(get_spectrumdataset_rad_max("spec", e_min=250 * u.GeV), observation) dataset_on_off = bkg_maker.run(dataset, observation) assert dataset_on_off.counts_off is not None assert len(caplog.records) == 0
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 reflected_bkg_maker(exclusion_mask): return ReflectedRegionsBackgroundMaker(exclusion_mask=exclusion_mask)
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", frame="galactic") 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", name="energy") e_true = MapAxis.from_bounds(0.05, 100, nbin=200, interp="log", unit="TeV", name="energy_true") stacked = SpectrumDatasetOnOff.create(region=on_region, e_reco=e_reco, e_true=e_true, name="stacked") dataset_maker = SpectrumDatasetMaker(containment_correction=False, selection=["counts", "aeff", "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])
from gammapy.visualization import plot_spectrum_datasets_off_regions data_store = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/") mask = data_store.obs_table["TARGET_NAME"] == "Crab" 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"]) e_reco = MapAxis.from_energy_bounds(0.1, 100, 30, unit="TeV") dataset_empty = SpectrumDataset.create(e_reco=e_reco, region=rectangle) 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")
def reflected_bkg_maker(exclusion_mask): finder = ReflectedRegionsFinder() return ReflectedRegionsBackgroundMaker( region_finder=finder, exclusion_mask=exclusion_mask, )