def setup_class(cls): filename = "$GAMMAPY_DATA/hess-dl3-dr1/data/hess_dl3_dr1_obs_id_020136.fits.gz" cls.edisp = EnergyDispersion2D.read(filename, hdu="EDISP") # Make a test case energy_axis_true = MapAxis.from_energy_bounds("0.1 TeV", "100 TeV", nbin=50, name="energy_true") migra_axis = MapAxis.from_bounds(0, 4, nbin=1000, node_type="edges", name="migra") offset_axis = MapAxis.from_bounds(0, 2.5, nbin=5, unit="deg", name="offset") energy_true = energy_axis_true.edges[:-1].reshape((-1, 1, 1)) sigma = 0.15 / (energy_true / (1 * u.TeV)).value**0.3 bias = 1e-3 * (energy_true - 1 * u.TeV).value cls.edisp2 = EnergyDispersion2D.from_gauss( energy_axis_true=energy_axis_true, migra_axis=migra_axis, bias=bias, sigma=sigma, offset_axis=offset_axis, )
def test_write(self): energy_axis_true = MapAxis.from_energy_bounds( "1 TeV", "10 TeV", nbin=10, name="energy_true" ) offset_axis = MapAxis.from_bounds( 0, 1, nbin=3, unit="deg", name="offset", node_type="edges" ) migra_axis = MapAxis.from_bounds(0, 3, nbin=3, name="migra", node_type="edges") axes = MapAxes([energy_axis_true, migra_axis, offset_axis]) data = np.ones(shape=axes.shape) edisp_test = EnergyDispersion2D(axes=axes) with pytest.raises(ValueError) as error: wrong_unit = u.m**2 EnergyDispersion2D(axes=axes, data=data * wrong_unit) assert error.match(f"Error: {wrong_unit} is not an allowed unit. {edisp_test.tag} requires {edisp_test.default_unit} data quantities.") edisp = EnergyDispersion2D(axes=axes, data=data) hdu = edisp.to_table_hdu() energy = edisp.axes["energy_true"].edges assert_equal(hdu.data["ENERG_LO"][0], energy[:-1].value) assert hdu.header["TUNIT1"] == edisp.axes["energy_true"].unit
def setup_class(cls): filename = "$GAMMAPY_DATA/hess-dl3-dr1/data/hess_dl3_dr1_obs_id_020136.fits.gz" cls.edisp = EnergyDispersion2D.read(filename, hdu="EDISP") # Make a test case e_true = np.logspace(-1.0, 2.0, 51) * u.TeV migra = np.linspace(0.0, 4.0, 1001) offset = np.linspace(0.0, 2.5, 5) * u.deg sigma = 0.15 / (e_true[:-1] / (1 * u.TeV)).value ** 0.3 bias = 1e-3 * (e_true[:-1] - 1 * u.TeV).value cls.edisp2 = EnergyDispersion2D.from_gauss(e_true, migra, bias, sigma, offset)
def setup(self): # TODO: use from_gauss method to create know edisp (see below) # At the moment only 1 test uses it (test_get_response) filename = "$GAMMAPY_DATA/tests/irf/hess/pa/hess_edisp_2d_023523.fits.gz" self.edisp = EnergyDispersion2D.read(filename, hdu="ENERGY DISPERSION") # Make a test case e_true = np.logspace(-1.0, 2.0, 51) * u.TeV migra = np.linspace(0.0, 4.0, 1001) offset = np.linspace(0.0, 2.5, 5) * u.deg sigma = 0.15 / (e_true[:-1] / (1 * u.TeV)).value**0.3 bias = 1e-3 * (e_true[:-1] - 1 * u.TeV).value self.edisp2 = EnergyDispersion2D.from_gauss(e_true, migra, bias, sigma, offset)
def energy_dispersion_3d_plot(irf_file_path, ax=None, hdu="ENERGY DISPERSION"): if not ax: fig = plt.figure(figsize=(10, 7), ) ax = fig.add_subplot(111, projection='3d') edisp = EnergyDispersion2D.read(irf_file_path, hdu=hdu) energy_reco = np.logspace(-2, 2, 20) * u.TeV offsets = np.linspace(0, 6, 7) * u.deg Z = [] for offset in offsets: erf = edisp.to_energy_dispersion(offset) zs = erf.get_resolution(energy_reco).value Z.append(zs) X, Y = np.meshgrid(energy_reco, offsets) Z = np.vstack(Z) mask = ~np.isfinite(Z) Z[mask] = np.nanmean(Z) Z = gaussian_filter(Z, sigma=0.8) X, Y, Z = np.log10(X.to_value('TeV')).ravel(), Y.ravel(), Z.ravel() ax.plot_trisurf(X, Y, Z, cmap='viridis', vmin=0, vmax=np.nanpercentile(Z, 99), antialiased=True) ax.xaxis.set_major_formatter(mticker.FuncFormatter(_log_tick_formatter)) return ax
def get_irfs(): filename = '$GAMMAPY_EXTRA/datasets/cta-1dc/caldb/data/cta//1dc/bcf/South_z20_50h/irf_file.fits' psf = EnergyDependentMultiGaussPSF.read(filename, hdu='POINT SPREAD FUNCTION') aeff = EffectiveAreaTable2D.read(filename, hdu='EFFECTIVE AREA') edisp = EnergyDispersion2D.read(filename, hdu='ENERGY DISPERSION') bkg = Background3D.read(filename, hdu='BACKGROUND') return dict(psf=psf, aeff=aeff, edisp=edisp, bkg=bkg)
def get_irfs(config, filename): '''Get IRFs from file. Parameters ---------- config : `dict` Configuration dictionary. filename : fits file IRFs file Returns ------- irfs : `dict` IRFs dictionary. ''' offset = Angle(config['selection']['offset_fov'] * u.deg) psf_fov = EnergyDependentMultiGaussPSF.read(filename, hdu='POINT SPREAD FUNCTION') psf = psf_fov.to_energy_dependent_table_psf(theta=offset) print(' psf', psf) aeff = EffectiveAreaTable2D.read(filename, hdu='EFFECTIVE AREA') edisp_fov = EnergyDispersion2D.read(filename, hdu='ENERGY DISPERSION') table = fits.open('irf_file.fits')['BACKGROUND'] table.columns.change_name(str('BGD'), str('Bgd')) table.header['TUNIT7'] = '1 / (MeV s sr)' bkg = Background3D.read(filename, hdu='BACKGROUND') irfs = dict(psf=psf, aeff=aeff, edisp=edisp_fov, bkg=bkg, offset=offset) return irfs
def prepare_dataset_simple(filename_dataset): """Prepare dataset for a given skymodel.""" log.info(f"Reading {IRF_FILE}") irfs = load_cta_irfs(IRF_FILE) edisp_gauss = EnergyDispersion2D.from_gauss( e_true=ENERGY_AXIS_TRUE.edges, migra=MIGRA_AXIS.edges, sigma=0.1, bias=0, offset=[0, 2, 4, 6, 8] * u.deg, ) irfs["edisp"] = edisp_gauss # irfs["aeff"].data.data = np.ones_like(irfs["aeff"].data.data) * 1e6 observation = Observation.create( obs_id=1001, pointing=POINTING, livetime=LIVETIME, irfs=irfs ) empty = MapDataset.create( WCS_GEOM, energy_axis_true=ENERGY_AXIS_TRUE, migra_axis=MIGRA_AXIS ) # maker = MapDatasetMaker(selection=["exposure", "edisp"]) # maker = MapDatasetMaker(selection=["exposure", "edisp", "background"]) maker = MapDatasetMaker(selection=["exposure", "edisp", "psf", "background"]) dataset = maker.run(empty, observation) filename_dataset.parent.mkdir(exist_ok=True, parents=True) log.info(f"Writing {filename_dataset}") dataset.write(filename_dataset, overwrite=True)
def test_make_edisp_kernel_map(): migra = MapAxis.from_edges(np.linspace(0.5, 1.5, 50), unit="", name="migra") etrue = MapAxis.from_energy_bounds(0.5, 2, 6, unit="TeV", name="energy_true") offset = MapAxis.from_edges(np.linspace(0.0, 2.0, 3), unit="deg", name="offset") ereco = MapAxis.from_energy_bounds(0.5, 2, 3, unit="TeV", name="energy") edisp = EnergyDispersion2D.from_gauss(energy_axis_true=etrue, migra_axis=migra, bias=0, sigma=0.01, offset_axis=offset) geom = WcsGeom.create(10, binsz=0.5, axes=[ereco, etrue]) pointing = SkyCoord(0, 0, frame="icrs", unit="deg") edispmap = make_edisp_kernel_map(edisp, pointing, geom) kernel = edispmap.get_edisp_kernel(pointing) assert_allclose(kernel.pdf_matrix[:, 0], (1.0, 1.0, 0.0, 0.0, 0.0, 0.0), atol=1e-14) assert_allclose(kernel.pdf_matrix[:, 1], (0.0, 0.0, 1.0, 1.0, 0.0, 0.0), atol=1e-14) assert_allclose(kernel.pdf_matrix[:, 2], (0.0, 0.0, 0.0, 0.0, 1.0, 1.0), atol=1e-14)
def test_energy_dispersion(): '''Test our energy dispersion is readable by gammapy''' pytest.importorskip('gammapy') from pyirf.io import create_energy_dispersion_hdu from gammapy.irf import EnergyDispersion2D e_bins = np.geomspace(0.1, 100, 31) * u.TeV migra_bins = np.linspace(0.2, 5, 101) fov_bins = [0, 1, 2, 3] * u.deg edisp = np.zeros((30, 100, 3)) edisp[:, 50, :] = 1.0 for point_like in [True, False]: with tempfile.NamedTemporaryFile(suffix='.fits') as f: hdu = create_energy_dispersion_hdu(edisp, e_bins, migra_bins, fov_bins, point_like=point_like) fits.HDUList([fits.PrimaryHDU(), hdu]).writeto(f.name) # test reading with gammapy works edisp2d = EnergyDispersion2D.read(f.name, 'EDISP') assert u.allclose(edisp, edisp2d.data.data, atol=1e-16)
def test_write(self): energy_axis_true = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=10, name="energy_true") offset_axis = MapAxis.from_bounds(0, 1, nbin=3, unit="deg", name="offset", node_type="edges") migra_axis = MapAxis.from_bounds(0, 3, nbin=3, name="migra", node_type="edges") axes = MapAxes([energy_axis_true, migra_axis, offset_axis]) data = np.ones(shape=axes.shape) edisp = EnergyDispersion2D(axes=axes, data=data) hdu = edisp.to_table_hdu() energy = edisp.axes["energy_true"].edges assert_equal(hdu.data["ENERG_LO"][0], energy[:-1].value) assert hdu.header["TUNIT1"] == edisp.axes["energy_true"].unit
def make_edisp_map_test(): pointing = SkyCoord(0, 0, unit="deg") energy_axis_true = MapAxis.from_energy_edges( energy_edges=[0.2, 0.7, 1.5, 2.0, 10.0] * u.TeV, name="energy_true", ) migra_axis = MapAxis(nodes=np.linspace(0.0, 3.0, 51), unit="", name="migra") offset_axis = MapAxis.from_nodes([0.0, 1.0, 2.0, 3.0] * u.deg, name="offset") edisp2d = EnergyDispersion2D.from_gauss( energy_axis_true=energy_axis_true, migra_axis=migra_axis, offset_axis=offset_axis, bias=0, sigma=0.2, ) geom = WcsGeom.create( skydir=pointing, binsz=1.0, width=5.0, axes=[migra_axis, energy_axis_true] ) aeff2d = fake_aeff2d() exposure_geom = geom.squash(axis_name="migra") exposure_map = make_map_exposure_true_energy(pointing, "1 h", aeff2d, exposure_geom) return make_edisp_map(edisp2d, pointing, geom, exposure_map)
def read(cls, filename): """Read from a FITS file. Parameters ---------- filename : `str` File containing the IRFs """ filename = str(make_path(filename)) hdu_list = fits.open(filename) aeff = EffectiveAreaTable2D.read(filename, hdu='EFFECTIVE AREA') bkg = Background3D.read(filename, hdu='BACKGROUND') edisp = EnergyDispersion2D.read(filename, hdu='ENERGY DISPERSION') psf = EnergyDependentMultiGaussPSF.read(filename, hdu='POINT SPREAD FUNCTION') if 'SENSITIVITY' in hdu_list: sensi = SensitivityTable.read(filename, hdu='SENSITIVITY') else: sensi = None return cls( aeff=aeff, bkg=bkg, edisp=edisp, psf=psf, ref_sensi=sensi, )
def plot_energy_resolution(irf_file, ax=None, **kwargs): """ Plot angular resolution from an IRF file Parameters ---------- irf_filename ax kwargs Returns ------- """ e2d = EnergyDispersion2D.read(irf_file, hdu='ENERGY DISPERSION') edisp = e2d.to_energy_dispersion('0 deg') energy_bin = np.logspace(-1.5, 1, 15) e = np.sqrt(energy_bin[1:] * energy_bin[:-1]) xerr = (e - energy_bin[:-1], energy_bin[1:] - e) r = edisp.get_resolution(e) if 'fmt' not in kwargs: kwargs['fmt'] = 'o' ax.errorbar(e, r, xerr=xerr, **kwargs) ax.set_xscale('log') ax.grid(True, which='both') ax.set_title('Energy resoluton') ax.set_xlabel('Energy [TeV]') ax.legend() return ax
def make_edisp_map_test(): etrue = [0.2, 0.7, 1.5, 2.0, 10.0] * u.TeV migra = np.linspace(0.0, 3.0, 51) offsets = np.array((0.0, 1.0, 2.0, 3.0)) * u.deg pointing = SkyCoord(0, 0, unit="deg") energy_axis = MapAxis( nodes=[0.2, 0.7, 1.5, 2.0, 10.0], unit="TeV", name="energy_true", node_type="edges", interp="log", ) migra_axis = MapAxis(nodes=np.linspace(0.0, 3.0, 51), unit="", name="migra") edisp2d = EnergyDispersion2D.from_gauss(etrue, migra, 0.0, 0.2, offsets) geom = WcsGeom.create( skydir=pointing, binsz=1.0, width=5.0, axes=[migra_axis, energy_axis] ) aeff2d = fake_aeff2d() exposure_geom = geom.squash(axis_name="migra") exposure_map = make_map_exposure_true_energy(pointing, "1 h", aeff2d, exposure_geom) return make_edisp_map(edisp2d, pointing, geom, exposure_map)
def test_write(self): energy_lo = np.logspace(0, 1, 11)[:-1] * u.TeV energy_hi = np.logspace(0, 1, 11)[1:] * u.TeV offset_lo = np.linspace(0, 1, 4)[:-1] * u.deg offset_hi = np.linspace(0, 1, 4)[1:] * u.deg migra_lo = np.linspace(0, 3, 4)[:-1] migra_hi = np.linspace(0, 3, 4)[1:] data = ( np.ones(shape=(len(energy_lo), len(migra_lo), len(offset_lo))) * u.cm * u.cm) edisp = EnergyDispersion2D( e_true_lo=energy_lo, e_true_hi=energy_hi, migra_lo=migra_lo, migra_hi=migra_hi, offset_lo=offset_lo, offset_hi=offset_hi, data=data, ) hdu = edisp.to_fits() energy = edisp.data.axis("energy_true").edges assert_equal(hdu.data["ENERG_LO"][0], energy[:-1].value) assert hdu.header["TUNIT1"] == edisp.data.axis("energy_true").unit
def test_edisp2d_pointlike(): filename = "$GAMMAPY_DATA/joint-crab/dl3/magic/run_05029748_DL3.fits" edisp = EnergyDispersion2D.read(filename) hdu = edisp.to_table_hdu() assert edisp.is_pointlike assert hdu.header["HDUCLAS3"] == "POINT-LIKE"
def check_edisp(label): irf_file = '1dc/1dc/caldb/data/cta/1dc/bcf/' + label + '/irf_file.fits' log.info(f'Reading {irf_file}') edisp = EnergyDispersion2D.read(irf_file, hdu='ENERGY DISPERSION') edisp.peek() filename = 'checks/irfs/' + label + '_edisp.png' log.info(f'Writing {filename}') plt.savefig(filename)
def setup(self): self.energy_lo = np.logspace(0, 1, 10)[:-1] * u.TeV self.energy_hi = np.logspace(0, 1, 10)[1:] * u.TeV self.energy_axis_true = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=9, name="energy_true") self.offset_lo = np.linspace(0, 1, 4)[:-1] * u.deg self.offset_hi = np.linspace(0, 1, 4)[1:] * u.deg self.offset_axis = MapAxis.from_bounds(0, 1, nbin=3, unit="deg", name="offset", node_type="edges") self.migra_lo = np.linspace(0, 3, 4)[:-1] self.migra_hi = np.linspace(0, 3, 4)[1:] self.migra_axis = MapAxis.from_bounds(0, 3, nbin=3, name="migra", node_type="edges") self.fov_lon_lo = np.linspace(-6, 6, 11)[:-1] * u.deg self.fov_lon_hi = np.linspace(-6, 6, 11)[1:] * u.deg self.fov_lon_axis = MapAxis.from_bounds(-6, 6, nbin=10, name="fov_lon") self.fov_lat_lo = np.linspace(-6, 6, 11)[:-1] * u.deg self.fov_lat_hi = np.linspace(-6, 6, 11)[1:] * u.deg self.fov_lat_axis = MapAxis.from_bounds(-6, 6, nbin=10, name="fov_lat") self.aeff_data = np.random.rand(9, 3) * u.cm * u.cm self.edisp_data = np.random.rand(9, 3, 3) self.bkg_data = np.random.rand(9, 10, 10) / u.MeV / u.s / u.sr self.aeff = EffectiveAreaTable2D( axes=[self.energy_axis_true, self.offset_axis], data=self.aeff_data.value, unit=self.aeff_data.unit, ) self.edisp = EnergyDispersion2D( axes=[ self.energy_axis_true, self.migra_axis, self.offset_axis, ], data=self.edisp_data, ) axes = [ self.energy_axis_true.copy(name="energy"), self.fov_lon_axis, self.fov_lat_axis, ] self.bkg = Background3D(axes=axes, data=self.bkg_data.value, unit=self.bkg_data.unit)
def get_irfs(): """Load CTA IRFs""" filename = "$GAMMAPY_DATA/cta-1dc/caldb/data/cta/1dc/bcf/South_z20_50h/irf_file.fits" psf = EnergyDependentMultiGaussPSF.read(filename, hdu="POINT SPREAD FUNCTION") aeff = EffectiveAreaTable2D.read(filename, hdu="EFFECTIVE AREA") edisp = EnergyDispersion2D.read(filename, hdu="ENERGY DISPERSION") bkg = Background3D.read(filename, hdu="BACKGROUND") return dict(psf=psf, aeff=aeff, edisp=edisp, bkg=bkg)
def get_edisp(geom, geom_etrue): filename = "$GAMMAPY_DATA/hess-dl3-dr1/data/hess_dl3_dr1_obs_id_020136.fits.gz" edisp2d = EnergyDispersion2D.read(filename, hdu="EDISP") energy = geom.axes["energy"].edges energy_true = geom_etrue.axes["energy_true"].edges edisp_kernel = edisp2d.to_edisp_kernel( offset="1.2 deg", energy=energy, energy_true=energy_true ) edisp = EDispKernelMap.from_edisp_kernel(edisp_kernel) return edisp
def read_energy_resolution(irf_filename): e2d = EnergyDispersion2D.read(irf_filename, hdu='ENERGY DISPERSION') edisp = e2d.to_energy_dispersion('0 deg') energy_bin = np.logspace(-1.5, 1, 15) energy, energy_err = bins_limits_to_errorbars(energy_bin[:-1], energy_bin[1:], log=True) e_res = edisp.get_resolution(energy) return energy_bin[1:], energy_bin[:-1], e_res
def read(cls, filename, offset='0.5 deg'): """Read from a FITS file. Compute RMF at 0.5 deg offset on fly. Parameters ---------- filename : `str` File containing the IRFs """ filename = str(make_path(filename)) with fits.open(filename, memmap=False) as hdulist: aeff = EffectiveAreaTable.from_hdulist(hdulist=hdulist) edisp = EnergyDispersion2D.read(filename, hdu='ENERGY DISPERSION') bkg = BgRateTable.from_hdulist(hdulist=hdulist) psf = Psf68Table.from_hdulist(hdulist=hdulist) sens = SensitivityTable.from_hdulist(hdulist=hdulist) # Create rmf with appropriate dimensions (e_reco->bkg, e_true->area) e_reco_min = bkg.energy.lo[0] e_reco_max = bkg.energy.hi[-1] e_reco_bin = bkg.energy.nbins e_reco_axis = EnergyBounds.equal_log_spacing( e_reco_min, e_reco_max, e_reco_bin, 'TeV', ) e_true_min = aeff.energy.lo[0] e_true_max = aeff.energy.hi[-1] e_true_bin = aeff.energy.nbins e_true_axis = EnergyBounds.equal_log_spacing( e_true_min, e_true_max, e_true_bin, 'TeV', ) rmf = edisp.to_energy_dispersion( offset=offset, e_reco=e_reco_axis, e_true=e_true_axis, ) return cls(aeff=aeff, bkg=bkg, edisp=edisp, psf=psf, sens=sens, rmf=rmf)
def test_energy_dispersion_gammapy(edisp_hdus): '''Test our energy dispersion is readable by gammapy''' from gammapy.irf import EnergyDispersion2D edisp, hdus = edisp_hdus for hdu in hdus: with tempfile.NamedTemporaryFile(suffix='.fits') as f: fits.HDUList([fits.PrimaryHDU(), hdu]).writeto(f.name) # test reading with gammapy works edisp2d = EnergyDispersion2D.read(f.name, 'EDISP') assert u.allclose(edisp, edisp2d.data.data, atol=1e-16)
def load(self): """Load HDU as appropriate class. TODO: this should probably go via an extensible registry. """ hdu_class = self.hdu_class filename = self.path() hdu = self.hdu_name if hdu_class == "events": from gammapy.data import EventList return EventList.read(filename, hdu=hdu) elif hdu_class == "gti": from gammapy.data import GTI return GTI.read(filename, hdu=hdu) elif hdu_class == "aeff_2d": from gammapy.irf import EffectiveAreaTable2D return EffectiveAreaTable2D.read(filename, hdu=hdu) elif hdu_class == "edisp_2d": from gammapy.irf import EnergyDispersion2D return EnergyDispersion2D.read(filename, hdu=hdu) elif hdu_class == "psf_table": from gammapy.irf import PSF3D return PSF3D.read(filename, hdu=hdu) elif hdu_class == "psf_3gauss": from gammapy.irf import EnergyDependentMultiGaussPSF return EnergyDependentMultiGaussPSF.read(filename, hdu=hdu) elif hdu_class == "psf_king": from gammapy.irf import PSFKing return PSFKing.read(filename, hdu=hdu) elif hdu_class == "bkg_2d": from gammapy.irf import Background2D return Background2D.read(filename, hdu=hdu) elif hdu_class == "bkg_3d": from gammapy.irf import Background3D return Background3D.read(filename, hdu=hdu) else: raise ValueError(f"Invalid hdu_class: {hdu_class}")
def load_irf(self): filename = os.path.join(self.outdir, "irf.fits.gz") with fits.open(filename, memmap=False) as hdulist: aeff = EffectiveAreaTable2D.from_hdulist(hdulist=hdulist) edisp = EnergyDispersion2D.read(filename, hdu="ENERGY DISPERSION") bkg_fits_table = hdulist["BACKGROUND"] bkg_table = Table.read(bkg_fits_table) energy_lo = bkg_table["ENERG_LO"].quantity energy_hi = bkg_table["ENERG_HI"].quantity bkg = bkg_table["BGD"].quantity axes = [ BinnedDataAxis(energy_lo, energy_hi, interpolation_mode="log", name="energy") ] bkg = BkgData(data=NDDataArray(axes=axes, data=bkg)) # Create rmf with appropriate dimensions (e_reco->bkg, e_true->area) e_reco_min = bkg.energy.lo[0] e_reco_max = bkg.energy.hi[-1] e_reco_bin = bkg.energy.nbins e_reco_axis = EnergyBounds.equal_log_spacing(e_reco_min, e_reco_max, e_reco_bin, "TeV") e_true_min = aeff.data.axes[0].lo[0] e_true_max = aeff.data.axes[0].hi[-1] e_true_bin = len(aeff.data.axes[0].bins) - 1 e_true_axis = EnergyBounds.equal_log_spacing(e_true_min, e_true_max, e_true_bin, "TeV") # Fake offset... rmf = edisp.to_energy_dispersion(offset=0.5 * u.deg, e_reco=e_reco_axis, e_true=e_true_axis) # This is required because in gammapy v0.8 # gammapy.spectrum.utils.integrate_model # calls the attribute aeff.energy which is an attribute of # EffectiveAreaTable and not of EffectiveAreaTable2D # WARNING the angle is not important, but only because we started with # on-axis data! TO UPDATE aeff = aeff.to_effective_area_table(Angle("1d")) self.irf = Irf(bkg=bkg, aeff=aeff, rmf=rmf)
def test_writeread(self, tmp_path): path = tmp_path / "tmp.fits" fits.HDUList([ fits.PrimaryHDU(), self.aeff.to_table_hdu(), self.edisp.to_table_hdu(), self.bkg.to_table_hdu(), ]).writeto(path) read_aeff = EffectiveAreaTable2D.read(path, hdu="EFFECTIVE AREA") assert_allclose(read_aeff.data.data, self.aeff_data) read_edisp = EnergyDispersion2D.read(path, hdu="ENERGY DISPERSION") assert_allclose(read_edisp.data.data, self.edisp_data) read_bkg = Background3D.read(path, hdu="BACKGROUND") assert_allclose(read_bkg.data.data, self.bkg_data)
def read(cls, filename, offset='0.5 deg'): """Read from a FITS file. Compute RMF at 0.5 deg offset on fly. Parameters ---------- filename : `str` File containing the IRFs """ filename = str(make_path(filename)) with fits.open(filename, memmap=False) as hdulist: aeff = EffectiveAreaTable.from_hdulist(hdulist=hdulist) edisp = EnergyDispersion2D.read(filename, hdu='ENERGY DISPERSION') bkg = BgRateTable.from_hdulist(hdulist=hdulist) psf = Psf68Table.from_hdulist(hdulist=hdulist) sens = SensitivityTable.from_hdulist(hdulist=hdulist) # Create rmf with appropriate dimensions (e_reco->bkg, e_true->area) e_reco_min = bkg.energy.lo[0] e_reco_max = bkg.energy.hi[-1] e_reco_bin = bkg.energy.nbins e_reco_axis = EnergyBounds.equal_log_spacing( e_reco_min, e_reco_max, e_reco_bin, 'TeV', ) e_true_min = aeff.energy.lo[0] e_true_max = aeff.energy.hi[-1] e_true_bin = aeff.energy.nbins e_true_axis = EnergyBounds.equal_log_spacing( e_true_min, e_true_max, e_true_bin, 'TeV', ) rmf = edisp.to_energy_dispersion( offset=offset, e_reco=e_reco_axis, e_true=e_true_axis, ) return cls( aeff=aeff, bkg=bkg, edisp=edisp, psf=psf, sens=sens, rmf=rmf )
def test_energy_dispersion_2d_to_gadf(): from gammapy.irf import EnergyDispersion2D from gammapy.maps import MapAxis energy_axis = MapAxis.from_energy_bounds(1 * u.TeV, 10 * u.TeV, nbin=3, name='energy_true') offset_axis = MapAxis.from_bounds(0 * u.deg, 2 * u.deg, nbin=2, name='offset') migra_axis = MapAxis.from_bounds(0.2, 5, nbin=5, interp='log', name='migra') data = np.zeros((energy_axis.nbin, migra_axis.nbin, offset_axis.nbin)) edisp = EnergyDispersion2D(data=data, axes=[energy_axis, migra_axis, offset_axis]) hdu = edisp.to_table_hdu(format='gadf-dl3') mandatory_columns = { 'ENERG_LO', 'ENERG_HI', 'MIGRA_LO', 'MIGRA_HI', 'THETA_LO', 'THETA_HI', 'MATRIX', } columns = {column.name for column in hdu.columns} missing = mandatory_columns.difference(columns) assert len(missing) == 0, f'GADF HDU missing required column(s) {missing}' header = hdu.header assert header['HDUCLASS'] == 'GADF' assert header[ 'HDUDOC'] == 'https://github.com/open-gamma-ray-astro/gamma-astro-data-formats' assert header['HDUVERS'] == '0.2' assert header['HDUCLAS1'] == 'RESPONSE' assert header['HDUCLAS2'] == 'EDISP' assert header['HDUCLAS3'] == 'FULL-ENCLOSURE' assert header['HDUCLAS4'] == 'EDISP_2D'
def get_irfs(config): filename = '$GAMMAPY_EXTRA/datasets/cta-1dc/caldb/data/cta//1dc/bcf/South_z20_50h/irf_file.fits' offset = Angle(config['selection']['offset_fov'] * u.deg) psf_fov = EnergyDependentMultiGaussPSF.read(filename, hdu='POINT SPREAD FUNCTION') psf = psf_fov.to_energy_dependent_table_psf(theta=offset) print(' psf', psf) aeff = EffectiveAreaTable2D.read(filename, hdu='EFFECTIVE AREA') edisp_fov = EnergyDispersion2D.read(filename, hdu='ENERGY DISPERSION') edisp = edisp_fov.to_energy_dispersion(offset=offset) # TODO: read background once it's working! # bkg = Background3D.read(filename, hdu='BACKGROUND') return dict(psf=psf, aeff=aeff, edisp=edisp)
def test_writeread(self, tmpdir): filename = str(tmpdir / "testirf.fits") fits.HDUList([ fits.PrimaryHDU(), self.aeff.to_fits(), self.edisp.to_fits(), self.bkg.to_fits(), ]).writeto(filename) read_aeff = EffectiveAreaTable2D.read(filename=filename, hdu="EFFECTIVE AREA") assert_allclose(read_aeff.data.data, self.aeff_data) read_edisp = EnergyDispersion2D.read(filename=filename, hdu="ENERGY DISPERSION") assert_allclose(read_edisp.data.data, self.edisp_data) read_bkg = Background3D.read(filename=filename, hdu="BACKGROUND") assert_allclose(read_bkg.data.data, self.bkg_data)
from astropy import units as u from gammapy.utils.fits import get_hdu from gammapy.irf import EnergyDispersion2D import matplotlib.pyplot as plt irf_path = 'perf_prod2/South_5h/irf_file.fits.gz' table_hdu_disp = get_hdu(irf_path + '[ENERGY DISPERSION]') e_disp_2d = EnergyDispersion2D.from_fits(table_hdu_disp) # Theta values are weird, nedd to be investiguated: # THETA_LO: 0., 4.5 # THETA_HI: 4.5, 9.0 e_disp = e_disp_2d.to_energy_dispersion(offset=4.5 * u.deg) #plt.figure('edisp') #e_disp.plot_matrix() #plt.show()