Пример #1
0
def make_test_psf_fits_table(filename, N_energy=15, N_theta=12):
    """
    Create a test FITS PSf file.

    A log-linear dependency in energy is assumed, where the size of
    the PSF decreases by a factor of tow over tow decades. The
    theta dependency is a parabola where at theta = 2 deg the size
    of the PSF has increased by 30%.

    Parameters
    ----------
    filename : str
        FITS file name
    N_energy : int (default 15)
        Number of energy bins
    N_theta : int (default 12)
        Number of theta bins
    """
    energies_all = np.logspace(-1, 2, N_energy + 1)
    energies_lo = energies_all[:-1]
    energies_hi = energies_all[1:]
    theta_lo = theta_hi = np.linspace(0, 2.2, N_theta)
    azimuth_lo = azimuth_hi = 0
    zenith_lo = zenith_hi = 0

    def sigma_energy_theta(energy, theta, sigma):
        # log-linear dependency of sigma with energy
        # m and b are choosen such, that at 100 TeV
        # we have sigma and at 0.1 TeV we have sigma/2
        m = -sigma / 6.
        b = sigma + m
        return (2 * b + m * np.log10(energy)) * (0.3 / 4 * theta ** 2 + 1)

    # Compute norms and sigmas values are taken from the psf.txt in
    # irf/test/data
    energies, thetas = np.meshgrid(energies_lo, theta_lo)

    sigmas = []
    for sigma in [0.0219206, 0.0905762, 0.0426358]:
        sigmas.append(sigma_energy_theta(energies, thetas, sigma))

    norms = []
    for norm in 302.654 * np.array([1, 0.0406003, 0.444632]):
        norms.append(norm * np.ones((N_theta, N_energy)))

    psf = EnergyDependentMultiGaussPSF(Quantity(energies_lo, 'TeV'),
                                       Quantity(energies_hi, 'TeV'),
                                       Quantity(theta_lo, 'deg'),
                                       sigmas, norms, azimuth=azimuth_hi,
                                       zenith=zenith_hi)
    psf.write(filename)
Пример #2
0
    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,
        )
Пример #3
0
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)
Пример #4
0
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
Пример #5
0
    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,
        )
Пример #6
0
def test_convolve_nd():
    energy_axis = MapAxis.from_edges(np.logspace(-1.0, 1.0, 4),
                                     unit="TeV",
                                     name="energy_true")
    geom = WcsGeom.create(binsz=0.02 * u.deg,
                          width=4.0 * u.deg,
                          axes=[energy_axis])
    m = Map.from_geom(geom)
    m.fill_by_coord([[0.2, 0.4], [-0.1, 0.6], [0.5, 3.6]])

    # TODO : build EnergyDependentTablePSF programmatically rather than using CTA 1DC IRF
    filename = (
        "$GAMMAPY_DATA/cta-1dc/caldb/data/cta//1dc/bcf/South_z20_50h/irf_file.fits"
    )
    psf = EnergyDependentMultiGaussPSF.read(filename,
                                            hdu="POINT SPREAD FUNCTION")
    table_psf = psf.to_energy_dependent_table_psf(theta=0.5 * u.deg)

    psf_kernel = PSFKernel.from_table_psf(table_psf,
                                          geom,
                                          max_radius=1 * u.deg)

    assert psf_kernel.psf_kernel_map.data.shape == (3, 101, 101)

    mc = m.convolve(psf_kernel)
    assert_allclose(mc.data.sum(axis=(1, 2)), [0, 1, 1], atol=1e-5)

    kernel_2d = Box2DKernel(3, mode="center")
    kernel_2d.normalize("peak")
    mc = m.convolve(kernel_2d.array)
    assert_allclose(mc.data[0, :, :].sum(), 0, atol=1e-5)
    assert_allclose(mc.data[1, :, :].sum(), 9, atol=1e-5)
Пример #7
0
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)
Пример #8
0
def get_psf(geom_etrue):
    filename = (
        "$GAMMAPY_DATA/cta-1dc/caldb/data/cta/1dc/bcf/South_z20_50h/irf_file.fits"
    )
    psf = EnergyDependentMultiGaussPSF.read(filename, hdu="POINT SPREAD FUNCTION")

    table_psf = psf.to_energy_dependent_table_psf(theta=0.5 * u.deg)
    psf_kernel = PSFKernel.from_table_psf(table_psf, geom_etrue, max_radius=0.5 * u.deg)
    return psf_kernel
Пример #9
0
def get_psf():
    filename = (
        "$GAMMAPY_DATA/cta-1dc/caldb/data/cta/1dc/bcf/South_z20_50h/irf_file.fits"
    )
    psf = EnergyDependentMultiGaussPSF.read(filename, hdu="POINT SPREAD FUNCTION")

    table_psf = psf.to_energy_dependent_table_psf(theta=0.5 * u.deg)
    psf_map = PSFMap.from_energy_dependent_table_psf(table_psf)
    return psf_map
Пример #10
0
def test_get_sigmas_and_norms():
    filename = "$GAMMAPY_DATA/cta-caldb/Prod5-South-20deg-AverageAz-14MSTs37SSTs.180000s-v0.1.fits.gz"

    psf_irf = EnergyDependentMultiGaussPSF.read(filename,
                                                hdu="POINT SPREAD FUNCTION")

    value = psf_irf.evaluate(energy_true=1 * u.TeV,
                             rad=0.03 * u.deg,
                             offset=3.5 * u.deg)
    assert_allclose(value, 78.25826069 * u.Unit("deg-2"))
Пример #11
0
def check_psf(label):
    irf_file = '1dc/1dc/caldb/data/cta/1dc/bcf/' + label + '/irf_file.fits'
    log.info(f'Reading {irf_file}')

    edisp = EnergyDependentMultiGaussPSF.read(irf_file,
                                              hdu='POINT SPREAD FUNCTION')
    edisp.peek()
    filename = 'checks/irfs/' + label + '_psf.png'
    log.info(f'Writing {filename}')
    plt.savefig(filename)
Пример #12
0
    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}")
Пример #13
0
def test_psf_cta_1dc():
    filename = (
        "$GAMMAPY_DATA/cta-1dc/caldb/data/cta/1dc/bcf/South_z20_50h/irf_file.fits"
    )
    psf_irf = EnergyDependentMultiGaussPSF.read(filename,
                                                hdu="POINT SPREAD FUNCTION")

    # Check that PSF is filled with 0 for energy / offset where no PSF info is given.
    # This is needed so that stacked PSF computation doesn't error out,
    # trying to interpolate for observations / energies where this occurs.
    psf = psf_irf.to_energy_dependent_table_psf("4.5 deg")
    psf = psf.table_psf_at_energy("0.05 TeV")
    assert_allclose(psf.evaluate(rad="0.03 deg").value, 0)

    # Check that evaluation works for an energy / offset where an energy is available
    psf = psf_irf.to_energy_dependent_table_psf("2 deg")
    psf = psf.table_psf_at_energy("1 TeV")
    assert_allclose(psf.containment_radius(0.68).deg, 0.052841, atol=1e-4)
Пример #14
0
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)
Пример #15
0
def test_psf_cta_1dc():
    filename = (
        "$GAMMAPY_DATA/cta-1dc/caldb/data/cta/1dc/bcf/South_z20_50h/irf_file.fits"
    )
    psf_irf = EnergyDependentMultiGaussPSF.read(filename, hdu="POINT SPREAD FUNCTION")

    # Check that PSF is filled with 0 for energy / offset where no PSF info is given.
    # This is needed so that stacked PSF computation doesn't error out,
    # trying to interpolate for observations / energies where this occurs.
    value = psf_irf.evaluate(
        energy_true=0.05 * u.TeV, rad=0.03 * u.deg, offset=4.5 * u.deg
    )
    assert_allclose(value, 0 * u.Unit("deg-2"))

    # Check that evaluation works for an energy / offset where an energy is available
    radius = psf_irf.containment_radius(
        fraction=0.68, energy_true=1 * u.TeV, offset=2 * u.deg
    )
    assert_allclose(radius, 0.052841 * u.deg, atol=1e-4)
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)
Пример #17
0
def get_psf():
    filename = (
        "$GAMMAPY_DATA/cta-1dc/caldb/data/cta/1dc/bcf/South_z20_50h/irf_file.fits"
    )
    psf = EnergyDependentMultiGaussPSF.read(filename, hdu="POINT SPREAD FUNCTION")

    geom = WcsGeom.create(
        skydir=(0, 0),
        frame="galactic",
        binsz=2,
        width=(2, 2),
        axes=[RAD_AXIS_DEFAULT, psf.axes["energy_true"]]
    )

    return make_psf_map(
        psf=psf,
        pointing=SkyCoord(0, 0.5, unit="deg", frame="galactic"),
        geom=geom,
        exposure_map=Map.from_geom(geom.squash("rad"), unit="cm2 s")
    )
Пример #18
0
def retrieve_psf_info(hdu_list, energies, theta, fractions, plot=False):
    """
    Retrieve psf information from psf fits file.

    Parameters
    ----------
    hdu_list : `~astropy.io.fits.HDUList`
            HDU list with ``POINT SPREAD FUNCTION``extension.
    plot : bool
        Make a containment radius vs. theta and energy plot.
    """
    from gammapy.irf import EnergyDependentMultiGaussPSF
    psf = EnergyDependentMultiGaussPSF.from_fits(hdu_list)
    energies = Quantity(energies, 'TeV')
    thetas = Quantity(theta, 'deg')
    print(psf.info(fractions=fractions, energies=energies, thetas=thetas))

    if plot:
        for fraction in fractions:
            filename = 'containment_R{0:.0f}_energy_theta.png'.format(100 * fraction)
            psf.plot_containment(fraction, filename)
# In[ ]:

# This is how for analysis you could slice out an `EnergyDispersion`
# object at a given offset:
edisp.to_energy_dispersion(offset="0 deg")

# ### Point spread function
#
# The point spread function (PSF) in this case is given as an analytical Gaussian model.

# In[ ]:

from gammapy.irf import EnergyDependentMultiGaussPSF

psf = EnergyDependentMultiGaussPSF.read(irf_filename,
                                        hdu="POINT SPREAD FUNCTION")
print(psf.info())

# In[ ]:

psf.peek()

# In[ ]:

# This is how for analysis you could slice out the PSF
# at a given field of view offset
psf.to_energy_dependent_table_psf("1 deg")

# ### Background
#
# The hadronic background for CTA DC-1 is given as a template model with an absolute rate that depends on `energy`, `detx` and `dety`. The coordinates `detx` and `dety` are angles in the "field of view" coordinate frame.
Пример #20
0
import matplotlib.pyplot as plt
from gammapy.irf import EnergyDependentMultiGaussPSF
filename = '$GAMMAPY_EXTRA/test_datasets/unbundled/irfs/psf.fits'
psf = EnergyDependentMultiGaussPSF.read(filename, hdu='POINT SPREAD FUNCTION')
psf.plot_containment(0.68, show_safe_energy=False)
plt.show()
Пример #21
0
 def psf(self):
     filename = "$GAMMAPY_DATA/tests/unbundled/irfs/psf.fits"
     return EnergyDependentMultiGaussPSF.read(filename,
                                              hdu="POINT SPREAD FUNCTION")
Пример #22
0
from gammapy.irf import (
    EnergyDependentMultiGaussPSF,
    EffectiveAreaTable2D,
    EnergyDispersion2D,
    Background3D,
)

filename = "$GAMMAPY_DATA/cta-1dc/data/baseline/gps/gps_baseline_110380.fits"
event_list = EventList.read(filename)
gti = GTI.read(filename)

filename = "$GAMMAPY_DATA/cta-1dc/caldb/data/cta/1dc/bcf/South_z20_50h/irf_file.fits"
aeff = EffectiveAreaTable2D.read(filename)
bkg = Background3D.read(filename)
edisp = EnergyDispersion2D.read(filename, hdu="Energy Dispersion")
psf = EnergyDependentMultiGaussPSF.read(filename, hdu="Point Spread Function")

obs = ObservationCTA(
    obs_id=event_list.table.meta["OBS_ID"],
    events=event_list,
    gti=gti,
    psf=psf,
    aeff=aeff,
    edisp=edisp,
    bkg=bkg,
    pointing_radec=event_list.pointing_radec,
    observation_live_time_duration=event_list.observation_live_time_duration,
    observation_dead_time_fraction=event_list.observation_dead_time_fraction,
)

print(obs)
Пример #23
0
from gammapy.irf import EnergyDependentMultiGaussPSF

irf_path = 'perf_prod2/South_5h/irf_file.fits.gz'

psf = EnergyDependentMultiGaussPSF.read(irf_path, hdu='POINT SPREAD FUNCTION')

psf.peek()