def test_containment(): g, g2 = Gauss2DPDF(sigma=1), Gauss2DPDF(sigma=2) m = MultiGauss2D(sigmas=[1]) m2 = MultiGauss2D(sigmas=[1, 2], norms=[3, 4]) for theta in [0, 0.1, 1, 5]: assert_allclose(m.containment_fraction(theta), g.containment_fraction(theta)) actual = m2.containment_fraction(theta) desired = 3 * g.containment_fraction( theta) + 4 * g2.containment_fraction(theta) assert_allclose(actual, desired)
def test_theta(): # Closure test m = MultiGauss2D(sigmas=[1, 2] * u.deg, norms=[3, 4]) for theta in [0, 0.1, 1, 5] * u.deg: c = m.containment_fraction(theta) t = m.containment_radius(c) assert_allclose(t, theta)
def test_theta(): # Closure test m = MultiGauss2D(sigmas=[1, 2], norms=[3, 4]) for theta in [0, 0.1, 1, 5]: c = m.containment_fraction(theta) t = m.containment_radius(c) assert_almost_equal(t, theta, decimal=5)
def test_call(): m = MultiGauss2D(sigmas=[1, 2], norms=[3, 4]) xy_max = 5 * m.max_sigma # integration range integral = scipy.integrate.dblquad(m, -xy_max, xy_max, lambda _: -xy_max, lambda _: xy_max)[0] assert_almost_equal(integral, 7, decimal=5)
def test_gauss_convolve(): # Convolution must add sigmas in square m = MultiGauss2D(sigmas=[3], norms=[5]) m2 = m.gauss_convolve(4, 6) assert_allclose(m2.sigmas, [5]) assert_allclose(m2.integral, 5 * 6) # Check that convolve did not change the original assert_allclose(m.sigmas, [3]) assert_allclose(m.norms, [5])
def to_MultiGauss2D(self, normalize=True): """Use this to compute containment angles and fractions. Note: We have to set norm = 2 * A * sigma ^ 2, because in MultiGauss2D norm represents the integral, and in HESS A represents the amplitude at 0. """ sigmas, norms = [], [] for ii in range(1, self.n_gauss() + 1): A = self.pars[f"A_{ii}"] sigma = self.pars[f"sigma_{ii}"] norm = self.pars["scale"] * 2 * A * sigma**2 sigmas.append(sigma) norms.append(norm) m = MultiGauss2D(sigmas, norms) if normalize: m.normalize() return m
def evaluate_direct(rad, **kwargs): """Evaluate psf model Parameters ---------- rad : `~astropy.units.Quantity` Rad value **kwargs : dict Parameters, see `required_parameters` Returns ------- value : `~numpy.ndarray` PSF value """ sigmas, norms = get_sigmas_and_norms(**kwargs) m = MultiGauss2D(sigmas=sigmas, norms=norms) m.normalize() return m(rad)
def evaluate_containment(rad, **kwargs): """Containment of the PSF at given axes coordinates Parameters ---------- rad : `~astropy.units.Quantity` Rad value **kwargs : dict Parameters, see `required_parameters` Returns ------- containment : `~numpy.ndarray` Containment """ sigmas, norms = get_sigmas_and_norms(**kwargs) m = MultiGauss2D(sigmas=sigmas, norms=norms) m.normalize() containment = m.containment_fraction(rad) return containment
def psf_at_energy_and_theta(self, energy, theta): """ Get `~gammapy.modeling.models.MultiGauss2D` model for given energy and theta. No interpolation is used. Parameters ---------- energy : `~astropy.units.u.Quantity` Energy at which a PSF is requested. theta : `~astropy.coordinates.Angle` Offset angle at which a PSF is requested. Returns ------- psf : `~gammapy.utils.gauss.MultiGauss2D` Multigauss PSF object. """ energy = u.Quantity(energy) theta = u.Quantity(theta) sigmas, norms = [], [] pars = {"A_1": 1} for interp_sigma in self._interp_sigmas: sigma = interp_sigma((theta, energy)) sigmas.append(sigma) for name, interp_norm in zip(["scale", "A_2", "A_3"], self._interp_norms): pars[name] = interp_norm((theta, energy)) for idx, sigma in enumerate(sigmas): a = pars[f"A_{idx + 1}"] norm = pars["scale"] * 2 * a * sigma**2 norms.append(norm) m = MultiGauss2D(sigmas, norms) m.normalize() return m
def test_integral_normalize(): m = MultiGauss2D(sigmas=[1, 2], norms=[3, 4]) assert_allclose(m.integral, 7) m.normalize() assert_allclose(m.integral, 1)
def test_dpdtheta2(): m = MultiGauss2D(sigmas=[1, 2], norms=[3, 4]) theta2_max = (7 * m.max_sigma)**2 integral = scipy.integrate.quad(m.dpdtheta2, 0, theta2_max)[0] assert_almost_equal(integral, 7, decimal=5)