Beispiel #1
0
    def sample_coord(self, map_coord, random_state=0):
        """Apply the energy dispersion corrections on the coordinates of a set of simulated events.

        Parameters
        ----------
        map_coord : `~gammapy.maps.MapCoord` object.
            Sequence of coordinates and energies of sampled events.
        random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`}
            Defines random number generator initialisation.
            Passed to `~gammapy.utils.random.get_random_state`.

        Returns
        -------
        `~gammapy.maps.MapCoord`.
            Sequence of Edisp-corrected coordinates of the input map_coord map.
        """
        random_state = get_random_state(random_state)
        migra_axis = self.edisp_map.geom.get_axis_by_name("migra")

        coord = {
            "skycoord": map_coord.skycoord.reshape(-1, 1),
            "energy_true": map_coord["energy_true"].reshape(-1, 1),
            "migra": migra_axis.center,
        }

        pdf_edisp = self.edisp_map.interp_by_coord(coord)

        sample_edisp = InverseCDFSampler(pdf_edisp, axis=1, random_state=random_state)
        pix_edisp = sample_edisp.sample_axis()
        migra = migra_axis.pix_to_coord(pix_edisp)

        energy_reco = map_coord["energy_true"] * migra

        return MapCoord.create({"skycoord": map_coord.skycoord, "energy": energy_reco})
Beispiel #2
0
    def sample_coord(self, n_events, random_state=0):
        """Sample position and energy of events.

        Parameters
        ----------
        n_events : int
            Number of events to sample.
        random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`}
            Defines random number generator initialisation.
            Passed to `~gammapy.utils.random.get_random_state`.

        Returns
        -------
        coords : `~gammapy.maps.MapCoord` object.
            Sequence of coordinates and energies of the sampled events.
        """

        random_state = get_random_state(random_state)
        sampler = InverseCDFSampler(pdf=self.data, random_state=random_state)

        coords_pix = sampler.sample(n_events)
        coords = self.geom.pix_to_coord(coords_pix[::-1])

        # TODO: pix_to_coord should return a MapCoord object
        axes_names = ["lon", "lat"] + self.geom.axes.names
        cdict = OrderedDict(zip(axes_names, coords))

        return MapCoord.create(cdict, frame=self.geom.frame)
Beispiel #3
0
def test_norm_dist_sampling():
    n_sampled = 1000
    x = np.linspace(-2, 2, n_sampled)

    mu, sigma = 0, 0.1
    pdf = gauss_dist(x=x, mu=mu, sigma=sigma)
    sampler = InverseCDFSampler(pdf=pdf, random_state=0)

    idx = sampler.sample(int(1e5))
    x_sampled = np.interp(idx, np.arange(n_sampled), x)

    assert_allclose(np.mean(x_sampled), mu, atol=0.01)
    assert_allclose(np.std(x_sampled), sigma, atol=0.005)
Beispiel #4
0
    def sample_time(self,
                    n_events,
                    t_min,
                    t_max,
                    t_delta="1 s",
                    random_state=0):
        """Sample arrival times of events.

        Parameters
        ----------
        n_events : int
            Number of events to sample.
        t_min : `~astropy.time.Time`
            Start time of the sampling.
        t_max : `~astropy.time.Time`
            Stop time of the sampling.
        t_delta : `~astropy.units.Quantity`
            Time step used for sampling of the temporal model.
        random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`}
            Defines random number generator initialisation.
            Passed to `~gammapy.utils.random.get_random_state`.

        Returns
        -------
        time : `~astropy.units.Quantity`
            Array with times of the sampled events.
        """
        time_unit = getattr(u, self.table.meta["TIMEUNIT"])

        t_min = Time(t_min)
        t_max = Time(t_max)
        t_delta = u.Quantity(t_delta)
        random_state = get_random_state(random_state)

        ontime = u.Quantity((t_max - t_min).sec, "s")
        t_stop = ontime.to_value(time_unit)

        # TODO: the separate time unit handling is unfortunate, but the quantity support for np.arange and np.interp
        #  is still incomplete, refactor once we change to recent numpy and astropy versions
        t_step = t_delta.to_value(time_unit)
        t = np.arange(0, t_stop, t_step)

        pdf = self.evaluate(t)

        sampler = InverseCDFSampler(pdf=pdf, random_state=random_state)
        time_pix = sampler.sample(n_events)[0]
        time = np.interp(time_pix, np.arange(len(t)), t) * time_unit

        return t_min + time
Beispiel #5
0
def test_uniform_dist_sampling():
    n_sampled = 1000
    x = np.linspace(-2, 2, n_sampled)

    a, b = -1, 1
    pdf = uniform_dist(x, a=a, b=b)
    sampler = InverseCDFSampler(pdf=pdf, random_state=0)

    idx = sampler.sample(int(1e4))
    x_sampled = np.interp(idx, np.arange(n_sampled), x)

    assert_allclose(np.mean(x_sampled), 0.5 * (a + b), atol=0.01)
    assert_allclose(np.std(x_sampled),
                    np.sqrt(1 / 3 * (a**2 + a * b + b**2)),
                    rtol=0.01)
Beispiel #6
0
def test_axis_sampling():
    n_sampled = 1000
    x = np.linspace(-2, 2, n_sampled)

    a, b = -1, 1
    pdf_uniform = uniform_dist(x, a=a, b=b)

    mu, sigma = 0, 0.1
    pdf_gauss = gauss_dist(x=x, mu=mu, sigma=sigma)

    pdf = np.vstack([pdf_gauss, pdf_uniform])
    sampler = InverseCDFSampler(pdf, random_state=0, axis=1)

    idx = sampler.sample_axis()
    x_sampled = np.interp(idx, np.arange(n_sampled), x)

    assert_allclose(x_sampled, [0.01042147, 0.43061014], rtol=1e-5)
Beispiel #7
0
    def sample_coord(self, map_coord, random_state=0):
        """Apply PSF corrections on the coordinates of a set of simulated events.

        Parameters
        ----------
        map_coord : `~gammapy.maps.MapCoord` object.
            Sequence of coordinates and energies of sampled events.
        random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`}
            Defines random number generator initialisation.
            Passed to `~gammapy.utils.random.get_random_state`.

        Returns
        -------
        corr_coord : `~gammapy.maps.MapCoord` object.
            Sequence of PSF-corrected coordinates of the input map_coord map.
        """

        random_state = get_random_state(random_state)
        rad_axis = self.psf_map.geom.axes["rad"]

        coord = {
            "skycoord": map_coord.skycoord.reshape(-1, 1),
            "energy_true": map_coord["energy_true"].reshape(-1, 1),
            "rad": rad_axis.center,
        }

        pdf = (
            self.psf_map.interp_by_coord(coord)
            * rad_axis.center.value
            * rad_axis.bin_width.value
        )

        sample_pdf = InverseCDFSampler(pdf, axis=1, random_state=random_state)
        pix_coord = sample_pdf.sample_axis()
        separation = rad_axis.pix_to_coord(pix_coord)

        position_angle = random_state.uniform(360, size=len(map_coord.lon)) * u.deg

        event_positions = map_coord.skycoord.directional_offset_by(
            position_angle=position_angle, separation=separation
        )
        return MapCoord.create(
            {"skycoord": event_positions, "energy_true": map_coord["energy_true"]}
        )