Exemplo n.º 1
0
def test_sky_to_fov():
    # test some simple cases
    lon, lat = sky_to_fov(1 * u.deg, 1 * u.deg, 0 * u.deg, 0 * u.deg)
    assert_allclose(lon.value, -1)
    assert_allclose(lat.value, 1)

    lon, lat = sky_to_fov(269 * u.deg, 0 * u.deg, 270 * u.deg, 0 * u.deg)
    assert_allclose(lon.value, 1)
    assert_allclose(lat.value, 0, atol=1e-7)

    lon, lat = sky_to_fov(1 * u.deg, 60 * u.deg, 0 * u.deg, 60 * u.deg)
    assert_allclose(lon.value, -0.5, rtol=1e-3)
    assert_allclose(lat.value, 0.003779, rtol=1e-3)

    # these are cross-checked with the
    # transformation as implemented in H.E.S.S.
    az = [51.320575, 50.899125, 52.154053, 48.233023]
    alt = [49.505451, 50.030165, 51.811739, 54.700102]
    az_pointing = [52.42056255, 52.24706061, 52.06655505, 51.86795724]
    alt_pointing = [51.11908203, 51.23454751, 51.35376141, 51.48385814]
    lon, lat = sky_to_fov(az * u.deg, alt * u.deg, az_pointing * u.deg,
                          alt_pointing * u.deg)
    assert_allclose(lon.value,
                    [0.7145614, 0.86603433, -0.05409698, 2.10295248],
                    rtol=1e-5)
    assert_allclose(lat.value,
                    [-1.60829115, -1.19643974, 0.45800984, 3.26844192],
                    rtol=1e-5)
Exemplo n.º 2
0
def make_map_background_irf(pointing,
                            ontime,
                            bkg,
                            geom,
                            oversampling=None,
                            use_region_center=True):
    """Compute background map from background IRFs.

    Parameters
    ----------
    pointing : `~gammapy.data.FixedPointingInfo` or `~astropy.coordinates.SkyCoord`
        Observation pointing

        - If a ``FixedPointingInfo`` is passed, FOV coordinates are properly computed.
        - If a ``SkyCoord`` is passed, FOV frame rotation is not taken into account.
    ontime : `~astropy.units.Quantity`
        Observation ontime. i.e. not corrected for deadtime
        see https://gamma-astro-data-formats.readthedocs.io/en/stable/irfs/full_enclosure/bkg/index.html#notes)
    bkg : `~gammapy.irf.Background3D`
        Background rate model
    geom : `~gammapy.maps.WcsGeom`
        Reference geometry
    oversampling: int
        Oversampling factor in energy, used for the background model evaluation.
    use_region_center: bool
        If geom is a RegionGeom, whether to just
        consider the values at the region center
        or the insted the sum over the whole region

    Returns
    -------
    background : `~gammapy.maps.WcsNDMap`
        Background predicted counts sky cube in reco energy
    """
    # TODO:
    #  This implementation can be improved in two ways:
    #  1. Create equal time intervals between TSTART and TSTOP and sum up the
    #  background IRF for each interval. This is instead of multiplying by
    #  the total ontime. This then handles the rotation of the FoV.
    #  2. Use the pointing table (does not currently exist in CTA files) to
    #  obtain the RA DEC and time for each interval. This then considers that
    #  the pointing might change slightly over the observation duration

    # Get altaz coords for map
    if oversampling is not None:
        geom = geom.upsample(factor=oversampling, axis_name="energy")

    coords = {"energy": geom.axes["energy"].edges.reshape((-1, 1, 1))}

    if not use_region_center:
        image_geom = geom.to_wcs_geom().to_image()
        region_coord, weights = geom.get_wcs_coord_and_weights()
        idx = image_geom.coord_to_idx(region_coord)
        sky_coord = region_coord.skycoord
        d_omega = image_geom.solid_angle().T[idx]
    else:
        image_geom = geom.to_image()
        map_coord = image_geom.get_coord()
        sky_coord = map_coord.skycoord
        d_omega = image_geom.solid_angle()

    if bkg.is_offset_dependent:
        coords["offset"] = sky_coord.separation(pointing)
    else:
        if isinstance(pointing, FixedPointingInfo):
            altaz_coord = sky_coord.transform_to(pointing.altaz_frame)

            # Compute FOV coordinates of map relative to pointing
            fov_lon, fov_lat = sky_to_fov(altaz_coord.az, altaz_coord.alt,
                                          pointing.altaz.az,
                                          pointing.altaz.alt)
        else:
            # Create OffsetFrame
            frame = SkyOffsetFrame(origin=pointing)
            pseudo_fov_coord = sky_coord.transform_to(frame)
            fov_lon = pseudo_fov_coord.lon
            fov_lat = pseudo_fov_coord.lat

        coords["fov_lon"] = fov_lon
        coords["fov_lat"] = fov_lat

    bkg_de = bkg.integrate_log_log(**coords, axis_name="energy")

    values = (bkg_de * d_omega * ontime).to_value("")

    if not use_region_center:
        data = np.sum(weights * values, axis=2)
    else:
        data = values

    bkg_map = Map.from_geom(geom, data=data)

    if oversampling is not None:
        bkg_map = bkg_map.downsample(factor=oversampling, axis_name="energy")

    return bkg_map
Exemplo n.º 3
0
def make_map_background_irf(pointing, ontime, bkg, geom, oversampling=None):
    """Compute background map from background IRFs.

    Parameters
    ----------
    pointing : `~gammapy.data.FixedPointingInfo` or `~astropy.coordinates.SkyCoord`
        Observation pointing

        - If a ``FixedPointingInfo`` is passed, FOV coordinates are properly computed.
        - If a ``SkyCoord`` is passed, FOV frame rotation is not taken into account.
    ontime : `~astropy.units.Quantity`
        Observation ontime. i.e. not corrected for deadtime
        see https://gamma-astro-data-formats.readthedocs.io/en/stable/irfs/full_enclosure/bkg/index.html#notes)
    bkg : `~gammapy.irf.Background3D`
        Background rate model
    geom : `~gammapy.maps.WcsGeom`
        Reference geometry
    oversampling: int
        Oversampling factor in energy, used for the background model evaluation.

    Returns
    -------
    background : `~gammapy.maps.WcsNDMap`
        Background predicted counts sky cube in reco energy
    """
    # TODO:
    #  This implementation can be improved in two ways:
    #  1. Create equal time intervals between TSTART and TSTOP and sum up the
    #  background IRF for each interval. This is instead of multiplying by
    #  the total ontime. This then handles the rotation of the FoV.
    #  2. Use the pointing table (does not currently exist in CTA files) to
    #  obtain the RA DEC and time for each interval. This then considers that
    #  the pointing might change slightly over the observation duration

    # Get altaz coords for map
    if oversampling is not None:
        geom = geom.upsample(factor=oversampling, axis="energy")

    map_coord = geom.to_image().get_coord()
    sky_coord = map_coord.skycoord

    if isinstance(pointing, FixedPointingInfo):
        altaz_coord = sky_coord.transform_to(pointing.altaz_frame)

        # Compute FOV coordinates of map relative to pointing
        fov_lon, fov_lat = sky_to_fov(altaz_coord.az, altaz_coord.alt,
                                      pointing.altaz.az, pointing.altaz.alt)
    else:
        # Create OffsetFrame
        frame = SkyOffsetFrame(origin=pointing)
        pseudo_fov_coord = sky_coord.transform_to(frame)
        fov_lon = pseudo_fov_coord.lon
        fov_lat = pseudo_fov_coord.lat

    energies = geom.get_axis_by_name("energy").edges

    bkg_de = bkg.evaluate_integrate(
        fov_lon=fov_lon,
        fov_lat=fov_lat,
        energy_reco=energies[:, np.newaxis, np.newaxis],
    )

    d_omega = geom.to_image().solid_angle()
    data = (bkg_de * d_omega * ontime).to_value("")
    bkg_map = WcsNDMap(geom, data=data)

    if oversampling is not None:
        bkg_map = bkg_map.downsample(factor=oversampling, axis="energy")

    return bkg_map