def test_energy_logspace(): energy = energy_logspace(emin="0.1 TeV", emax="10 TeV", nbins=3) assert energy.unit == "TeV" assert_allclose(energy.value, [0.1, 1, 10]) energy = energy_logspace(emin=0.1, emax=10, nbins=3, unit="TeV") assert energy.unit == "TeV" assert_allclose(energy.value, [0.1, 1, 10]) energy = energy_logspace(emin="0.1 TeV", emax="10 TeV", nbins=1, per_decade=True) assert energy.unit == "TeV" assert_allclose(energy.value, [0.1, 10])
def test_exporter(self): # Check RMF exporter offset = Angle(0.612, "deg") e_reco = energy_logspace(1, 10, 7, "TeV") e_true = energy_logspace(0.8, 5, 5, "TeV") rmf = self.edisp.to_energy_dispersion(offset, e_true=e_true, e_reco=e_reco) assert_allclose(rmf.data.data[2, 3], 0.08, atol=5e-2) # same tolerance as above actual = rmf.pdf_matrix[2] e_val = np.sqrt(e_true[2] * e_true[3]) desired = self.edisp.get_response(offset, e_val, e_reco) assert_equal(actual, desired)
def table_model(): energy_edges = energy_logspace(0.1 * u.TeV, 100 * u.TeV, 1000) energy = np.sqrt(energy_edges[:-1] * energy_edges[1:]) model = PowerLawSpectralModel(index=2.3, amplitude="4 cm-2 s-1 TeV-1", reference="1 TeV") dnde = model(energy) return TemplateSpectralModel(energy, dnde, 1)
def table_model(): energy_edges = energy_logspace(0.1 * u.TeV, 100 * u.TeV, 1000) energy = np.sqrt(energy_edges[:-1] * energy_edges[1:]) index = 2.3 * u.Unit("") amplitude = 4 / u.cm**2 / u.s / u.TeV reference = 1 * u.TeV pl = PowerLawSpectralModel(index, amplitude, reference) flux = pl(energy) return TemplateSpectralModel(energy, flux, 1 * u.Unit(""))
def test_make_mean_edisp(data_store): position = SkyCoord(83.63, 22.01, unit="deg") obs1 = data_store.obs(23523) obs2 = data_store.obs(23592) observations = Observations([obs1, obs2]) e_true = energy_logspace(0.01, 150, 81, "TeV") e_reco = energy_logspace(0.5, 100, 16, "TeV") rmf = make_mean_edisp(observations, position=position, e_true=e_true, e_reco=e_reco) assert len(rmf.e_true.center) == 80 assert len(rmf.e_reco.center) == 15 assert_quantity_allclose(rmf.data.data[53, 8], 0.056, atol=2e-2) rmf2 = make_mean_edisp( observations, position=position, e_true=e_true, e_reco=e_reco, low_reco_threshold="1 TeV", high_reco_threshold="60 TeV", ) i2 = np.where(rmf2.data.evaluate(e_reco="0.8 TeV") != 0)[0] assert len(i2) == 0 i2 = np.where(rmf2.data.evaluate(e_reco="61 TeV") != 0)[0] assert len(i2) == 0 i = np.where(rmf.data.evaluate(e_reco="1.5 TeV") != 0)[0] i2 = np.where(rmf2.data.evaluate(e_reco="1.5 TeV") != 0)[0] assert_equal(i, i2) i = np.where(rmf.data.evaluate(e_reco="40 TeV") != 0)[0] i2 = np.where(rmf2.data.evaluate(e_reco="40 TeV") != 0)[0] assert_equal(i, i2)
def config(): """Get test config, extend to several scenarios""" model = PowerLaw( index=2, amplitude=1e-11 * u.Unit("cm-2 s-1 TeV-1"), reference=1 * u.TeV ) pos = SkyCoord(83.63, 22.01, unit="deg", frame="icrs") radius = Angle(0.11, "deg") on_region = CircleSkyRegion(pos, radius) fp_binning = energy_logspace(1, 50, 5, "TeV") return dict( outdir=None, background=dict(on_region=on_region), extraction=dict(), fit=dict(model=model), fp_binning=fp_binning, )
def table_psf_in_energy_band(self, energy_band, spectrum=None, n_bins=11, **kwargs): """Average PSF in a given energy band. Expected counts in sub energy bands given the given exposure and spectrum are used as weights. Parameters ---------- energy_band : `~astropy.units.Quantity` Energy band spectrum : `SpectralModel` Spectral model used for weighting the PSF. Default is a power law with index=2. n_bins : int Number of energy points in the energy band, used to compute the weigthed PSF. Returns ------- psf : `TablePSF` Table PSF """ from ..spectrum.models import PowerLaw, TableModel if spectrum is None: spectrum = PowerLaw() exposure = TableModel(self.energy, self.exposure) e_min, e_max = energy_band energy = energy_logspace(emin=e_min, emax=e_max, nbins=n_bins) weights = (spectrum * exposure)(energy) weights /= weights.sum() psf_value = self.evaluate(energy=energy) psf_value_weighted = weights[:, np.newaxis] * psf_value return TablePSF(self.rad, psf_value_weighted.sum(axis=0), **kwargs)
def test_apply_containment_fraction(): n_edges_energy = 5 energy = energy_logspace(0.1, 10.0, nbins=n_edges_energy + 1, unit="TeV") area = np.ones(n_edges_energy) * 4 * u.m**2 aeff = EffectiveAreaTable(energy[:-1], energy[1:], data=area) nrad = 100 rad = Angle(np.linspace(0, 0.5, nrad), "deg") psf_table = TablePSF.from_shape(shape="disk", width="0.2 deg", rad=rad) psf_values = (np.resize(psf_table.psf_value.value, (n_edges_energy, nrad)) * psf_table.psf_value.unit) edep_psf_table = EnergyDependentTablePSF(aeff.energy.center, rad, psf_value=psf_values) new_aeff = apply_containment_fraction(aeff, edep_psf_table, Angle("0.1 deg")) assert_allclose(new_aeff.data.data.value, 1.0, rtol=5e-4) assert new_aeff.data.data.unit == "m2"
def plot_containment_vs_energy( self, fractions=[0.68, 0.95], thetas=Angle([0, 1], "deg"), ax=None ): """Plot containment fraction as a function of energy. """ import matplotlib.pyplot as plt ax = plt.gca() if ax is None else ax energy = energy_logspace(self.energy_lo[0], self.energy_hi[-1], 100) for theta in thetas: for fraction in fractions: radius = self.containment_radius(energy, theta, fraction) label = f"{theta.deg} deg, {100 * fraction:.1f}%" ax.plot(energy.value, radius.value, label=label) ax.semilogx() ax.legend(loc="best") ax.set_xlabel("Energy (TeV)") ax.set_ylabel("Containment radius (deg)")
@pytest.mark.parametrize( "pars", [ { "energy": None, "rad": None, "energy_shape": (32, ), "psf_energy": 865.9643, "rad_shape": (144, ), "psf_rad": 0.0015362848, "psf_exposure": 3.14711e12, "psf_value_shape": (32, 144), "psf_value": 4369.96391, }, { "energy": energy_logspace(1, 10, 101, "TeV"), "rad": None, "energy_shape": (101, ), "psf_energy": 1412.537545, "rad_shape": (144, ), "psf_rad": 0.0015362848, "psf_exposure": 4.688142e12, "psf_value_shape": (101, 144), "psf_value": 3726.58798, }, { "energy": None, "rad": Angle(np.arange(0, 2, 0.002), "deg"), "energy_shape": (32, ), "psf_energy": 865.9643, "rad_shape": (1000, ),
def test_wrong_init(self): bins = energy_logspace(1, 10, 8, "TeV") with pytest.raises(ValueError): CountsSpectrum(data=self.counts, energy_lo=bins[:-1], energy_hi=bins[1:])
def setup(self): self.counts = [0, 0, 2, 5, 17, 3] self.bins = energy_logspace(1, 10, 7, "TeV") self.spec = CountsSpectrum( data=self.counts, energy_lo=self.bins[:-1], energy_hi=self.bins[1:] )
def _default_plot_ebounds(self): energy = self.energy return energy_logspace(energy.min(), energy.max(), 50)