Example #1
0
 def __init__(self, energy_lo, energy_hi, data):
     axes = [
         BinnedDataAxis(energy_lo,
                        energy_hi,
                        interpolation_mode='log',
                        name='energy'),
     ]
     self.data = NDDataArray(axes=axes, data=data)
Example #2
0
    def load_irf(self):
        filename = os.path.join(self.outdir, "irf.fits.gz")
        with fits.open(filename, memmap=False) as hdulist:
            aeff = EffectiveAreaTable2D.from_hdulist(hdulist=hdulist)
            edisp = EnergyDispersion2D.read(filename, hdu="ENERGY DISPERSION")

            bkg_fits_table = hdulist["BACKGROUND"]
            bkg_table = Table.read(bkg_fits_table)
            energy_lo = bkg_table["ENERG_LO"].quantity
            energy_hi = bkg_table["ENERG_HI"].quantity
            bkg = bkg_table["BGD"].quantity

            axes = [
                BinnedDataAxis(energy_lo,
                               energy_hi,
                               interpolation_mode="log",
                               name="energy")
            ]
            bkg = BkgData(data=NDDataArray(axes=axes, data=bkg))

        # Create rmf with appropriate dimensions (e_reco->bkg, e_true->area)
        e_reco_min = bkg.energy.lo[0]
        e_reco_max = bkg.energy.hi[-1]
        e_reco_bin = bkg.energy.nbins
        e_reco_axis = EnergyBounds.equal_log_spacing(e_reco_min, e_reco_max,
                                                     e_reco_bin, "TeV")

        e_true_min = aeff.data.axes[0].lo[0]
        e_true_max = aeff.data.axes[0].hi[-1]
        e_true_bin = len(aeff.data.axes[0].bins) - 1
        e_true_axis = EnergyBounds.equal_log_spacing(e_true_min, e_true_max,
                                                     e_true_bin, "TeV")

        # Fake offset...
        rmf = edisp.to_energy_dispersion(offset=0.5 * u.deg,
                                         e_reco=e_reco_axis,
                                         e_true=e_true_axis)

        # This is required because in gammapy v0.8
        # gammapy.spectrum.utils.integrate_model
        # calls the attribute aeff.energy which is an attribute of
        # EffectiveAreaTable and not of  EffectiveAreaTable2D
        # WARNING the angle is not important, but only because we started with
        # on-axis data! TO UPDATE
        aeff = aeff.to_effective_area_table(Angle("1d"))

        self.irf = Irf(bkg=bkg, aeff=aeff, rmf=rmf)
Example #3
0
    def load_irf(self):
        filename = os.path.join(self.outdir, 'irf.fits.gz')
        with fits.open(filename, memmap=False) as hdulist:
            aeff = EffectiveAreaTable.from_hdulist(hdulist=hdulist)
            edisp = EnergyDispersion2D.read(filename, hdu="ENERGY DISPERSION")

            bkg_fits_table = hdulist["BACKGROUND"]
            bkg_table = Table.read(bkg_fits_table)
            energy_lo = bkg_table["ENERG_LO"].quantity
            energy_hi = bkg_table["ENERG_HI"].quantity
            bkg = bkg_table["BGD"].quantity

            axes = [
                BinnedDataAxis(
                    energy_lo, energy_hi, interpolation_mode="log", name="energy"
                )
            ]
            bkg = BkgData(data=NDDataArray(axes=axes, data=bkg))

        # Create rmf with appropriate dimensions (e_reco->bkg, e_true->area)
        e_reco_min = bkg.energy.lo[0]
        e_reco_max = bkg.energy.hi[-1]
        e_reco_bin = bkg.energy.nbins
        e_reco_axis = EnergyBounds.equal_log_spacing(
            e_reco_min, e_reco_max, e_reco_bin, "TeV"
        )

        e_true_min = aeff.energy.lo[0]
        e_true_max = aeff.energy.hi[-1]
        e_true_bin = aeff.energy.nbins
        e_true_axis = EnergyBounds.equal_log_spacing(
            e_true_min, e_true_max, e_true_bin, "TeV"
        )

        # Fake offset...
        rmf = edisp.to_energy_dispersion(
            offset=0.5 * u.deg, e_reco=e_reco_axis, e_true=e_true_axis
        )

        self.irf = Irf(bkg=bkg, aeff=aeff, rmf=rmf)
def cta_perf_root_to_fits(root_filename, fits_filename):
    """
    Convert CTA performance file from ROOT to FITS format.

    Parameters
    ----------
    root_filename : str
        Input ROOT filename
    fits_filename : str
        Output FITS filename
    """
    from ROOT import TFile

    print('Reading {}'.format(root_filename))
    root_file = TFile(root_filename)

    # Bg rate
    bg_rate = hist1d_to_table(hist=root_file.Get('BGRate'))
    # ENERG_LO
    bg_rate.rename_column('x_bin_lo', 'ENERG_LO')
    bg_rate['ENERG_LO'].unit = u.TeV
    bg_rate['ENERG_LO'].format = 'E'
    bg_rate.replace_column('ENERG_LO', 10 ** (bg_rate['ENERG_LO']))
    # ENERG_HI
    bg_rate.rename_column('x_bin_hi', 'ENERG_HI')
    bg_rate['ENERG_HI'].unit = u.TeV
    bg_rate['ENERG_HI'].format = 'E'
    bg_rate.replace_column('ENERG_HI', 10 ** (bg_rate['ENERG_HI']))
    # BGD
    bg_rate.rename_column('y', 'BGD')
    bg_rate['BGD'].unit = u.Hz
    bg_rate['BGD'].format = 'E'

    bg_rate_hdu = fits.BinTableHDU.from_columns([
        fits.Column('ENERG_LO',
                    bg_rate['ENERG_LO'].format,
                    unit=bg_rate['ENERG_LO'].unit.to_string(),
                    array=bg_rate['ENERG_LO']),
        fits.Column('ENERG_HI',
                    bg_rate['ENERG_HI'].format,
                    unit=bg_rate['ENERG_HI'].unit.to_string(),
                    array=bg_rate['ENERG_HI']),
        fits.Column('BGD',
                    bg_rate['BGD'].format,
                    unit=bg_rate['BGD'].unit.to_string(),
                    array=bg_rate['BGD']),
    ])

    bg_rate_hdu.header.set("EXTNAME", "BACKGROUND")

    # EffectiveAreaEtrue
    area = hist1d_to_table(hist=root_file.Get('EffectiveAreaEtrue'))
    # ENERG_LO
    area.rename_column('x_bin_lo', 'ENERG_LO')
    area['ENERG_LO'].unit = u.TeV
    area['ENERG_LO'].format = 'E'
    area.replace_column('ENERG_LO', 10 ** (area['ENERG_LO']))
    # ENERG_HI
    area.rename_column('x_bin_hi', 'ENERG_HI')
    area['ENERG_HI'].unit = u.TeV
    area['ENERG_HI'].format = 'E'
    area.replace_column('ENERG_HI', 10 ** (area['ENERG_HI']))
    # EFFAREA
    area.rename_column('y', 'SPECRESP')
    area['SPECRESP'].unit = u.meter * u.meter
    area['SPECRESP'].format = 'E'
    area.replace_column('SPECRESP', area['SPECRESP'])

    area_hdu = fits.BinTableHDU.from_columns([
        fits.Column('ENERG_LO',
                    area['ENERG_LO'].format,
                    unit=area['ENERG_LO'].unit.to_string(),
                    array=area['ENERG_LO']),
        fits.Column('ENERG_HI',
                    area['ENERG_HI'].format,
                    unit=area['ENERG_HI'].unit.to_string(),
                    array=area['ENERG_HI']),
        fits.Column('SPECRESP',
                    area['SPECRESP'].format,
                    unit=area['SPECRESP'].unit.to_string(),
                    array=area['SPECRESP']),
    ])

    area_hdu.header.set("EXTNAME", "SPECRESP")

    # PSF
    psf = hist1d_to_table(hist=root_file.Get('AngRes'))
    # ENERG_LO
    psf.rename_column('x_bin_lo', 'ENERG_LO')
    psf['ENERG_LO'].unit = u.TeV
    psf['ENERG_LO'].format = 'E'
    psf.replace_column('ENERG_LO', 10 ** (psf['ENERG_LO']))
    # ENERG_HI
    psf.rename_column('x_bin_hi', 'ENERG_HI')
    psf['ENERG_HI'].unit = u.TeV
    psf['ENERG_HI'].format = 'E'
    psf.replace_column('ENERG_HI', 10 ** (psf['ENERG_HI']))
    # PSF68
    psf.rename_column('y', 'PSF68')
    psf['PSF68'].unit = u.degree
    psf['PSF68'].format = 'E'
    psf.replace_column('PSF68', psf['PSF68'])

    psf_hdu = fits.BinTableHDU.from_columns([
        fits.Column('ENERG_LO',
                    psf['ENERG_LO'].format,
                    unit=psf['ENERG_LO'].unit.to_string(),
                    array=psf['ENERG_LO']),
        fits.Column('ENERG_HI',
                    psf['ENERG_HI'].format,
                    unit=psf['ENERG_HI'].unit.to_string(),
                    array=psf['ENERG_HI']),
        fits.Column('PSF68',
                    psf['PSF68'].format,
                    unit=psf['PSF68'].unit.to_string(),
                    array=psf['PSF68']),
    ])

    psf_hdu.header.set("EXTNAME", "POINT SPREAD FUNCTION")

    # MigMatrix (x=e_reco, y=e_true, z=prob)
    histo_edisp = root_file.Get('MigMatrix')
    # data
    data = TH2_to_FITS_data(hist=histo_edisp, flipx=False)
    # get e_reco
    x_axis = histo_edisp.GetXaxis()
    x_nbins = x_axis.GetNbins()
    x_min = 10 ** (x_axis.GetBinLowEdge(1))
    x_max = 10 ** (x_axis.GetBinUpEdge(x_nbins))
    e_reco = BinnedDataAxis.logspace(x_min, x_max, x_nbins, unit=u.TeV)
    # get e_true
    y_axis = histo_edisp.GetYaxis()
    y_nbins = y_axis.GetNbins()
    y_min = 10 ** (y_axis.GetBinLowEdge(1))
    y_max = 10 ** (y_axis.GetBinUpEdge(y_nbins))
    e_true = BinnedDataAxis.logspace(y_min, y_max, y_nbins, unit=u.TeV)
    e_disp = EnergyDispersion(data=data, e_true=e_true, e_reco=e_reco)

    edisp_hdus = e_disp.to_hdulist()

    # Sensitivity
    sens = hist1d_to_table(hist=root_file.Get('DiffSens'))
    # ENERG_LO
    sens.rename_column('x_bin_lo', 'ENERG_LO')
    sens['ENERG_LO'].unit = u.TeV
    sens['ENERG_LO'].format = 'E'
    sens.replace_column('ENERG_LO', 10 ** (sens['ENERG_LO']))
    # ENERG_HI
    sens.rename_column('x_bin_hi', 'ENERG_HI')
    sens['ENERG_HI'].unit = u.TeV
    sens['ENERG_HI'].format = 'E'
    sens.replace_column('ENERG_HI', 10 ** (sens['ENERG_HI']))
    # BGD
    sens.rename_column('y', 'SENSITIVITY')
    sens['SENSITIVITY'].unit = u.erg / (u.cm * u.cm * u.s)
    sens['SENSITIVITY'].format = 'E'

    sens_hdu = fits.BinTableHDU.from_columns([
        fits.Column('ENERG_LO',
                    sens['ENERG_LO'].format,
                    unit=sens['ENERG_LO'].unit.to_string(),
                    array=sens['ENERG_LO']),
        fits.Column('ENERG_HI',
                    sens['ENERG_HI'].format,
                    unit=sens['ENERG_HI'].unit.to_string(),
                    array=sens['ENERG_HI']),
        fits.Column('SENSITIVITY',
                    sens['SENSITIVITY'].format,
                    unit=sens['SENSITIVITY'].unit.to_string(),
                    array=sens['SENSITIVITY']),
    ])

    sens_hdu.header.set("EXTNAME", "SENSITIVITY")

    hdulist = fits.HDUList([
        edisp_hdus[0], area_hdu, psf_hdu,
        edisp_hdus[1], edisp_hdus[2],
        bg_rate_hdu, sens_hdu,
    ])

    print('Writing {}'.format(fits_filename))
    hdulist.writeto(fits_filename, overwrite=True)
Example #5
0
plt.xlabel("{} [{}]".format(nddata.axes[0].name, nddata.axes[0].unit))
plt.ylabel("{} [{}]".format("Exposure", nddata.data.unit))
plt.legend();


# ## 2D example
# 
# Another common use case is to store a Quantity as a function of field of view offset and energy. The following shows how to use the NDDataArray to slice the data array at any values of offset and energy

# In[ ]:


energy_data = EnergyBounds.equal_log_spacing(1, 10, 50, unit=u.TeV)
energy_axis = BinnedDataAxis(
    lo=energy_data.lower_bounds,
    hi=energy_data.upper_bounds,
    name="energy",
    interpolation_mode="log",
)
offset_data = np.linspace(0, 2, 4) * u.deg
offset_axis = DataAxis(offset_data, name="offset")

data_temp = 10 * np.exp(-energy_data.log_centers.value / 10)
data = np.outer(data_temp, (offset_data.value + 1))

nddata2d = NDDataArray(
    axes=[energy_axis, offset_axis], data=data * u.Unit("cm-2 s-1 TeV-1")
)

print(nddata2d)
extent_x = nddata2d.axis("energy").bins[[0, -1]].value
extent_y = nddata2d.axis("offset").nodes[[0, -1]].value