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)
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)
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)
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