def test_compute_flux_points_dnde_exp(method): """ Tests against analytical result or result from gammapy.spectrum.powerlaw. """ model = ExpTestModel() e_min = [1.0, 10.0] * u.TeV e_max = [10.0, 100.0] * u.TeV table = Table() table.meta["SED_TYPE"] = "flux" table["e_min"] = e_min table["e_max"] = e_max flux = model.integral(e_min, e_max) table["flux"] = flux if method == "log_center": e_ref = np.sqrt(e_min * e_max) elif method == "table": e_ref = [2.0, 20.0] * u.TeV table["e_ref"] = e_ref elif method == "lafferty": e_ref = FluxPoints._e_ref_lafferty(model, e_min, e_max) result = FluxPoints(table).to_sed_type("dnde", model=model, method=method) # Test energy actual = result.e_ref assert_quantity_allclose(actual, e_ref, rtol=1e-8) # Test flux actual = result.table["dnde"].quantity desired = model(e_ref) assert_quantity_allclose(actual, desired, rtol=1e-8)
def flux_points(self): """Flux points (`~gammapy.spectrum.FluxPoints`).""" table = Table() table.meta["SED_TYPE"] = "flux" table["e_min"] = self._ebounds[:-1] table["e_max"] = self._ebounds[1:] flux = self.data["Flux_Band"] flux_err = self.data["Unc_Flux_Band"] e2dnde = self.data["nuFnu"] table["flux"] = flux table["flux_errn"] = np.abs(flux_err[:, 0]) table["flux_errp"] = flux_err[:, 1] table["e2dnde"] = e2dnde table["e2dnde_errn"] = np.abs(e2dnde * flux_err[:, 0] / flux) table["e2dnde_errp"] = e2dnde * flux_err[:, 1] / flux is_ul = np.isnan(table["flux_errn"]) table["is_ul"] = is_ul # handle upper limits table["flux_ul"] = np.nan * flux_err.unit flux_ul = compute_flux_points_ul(table["flux"], table["flux_errp"]) table["flux_ul"][is_ul] = flux_ul[is_ul] table["e2dnde_ul"] = np.nan * e2dnde.unit e2dnde_ul = compute_flux_points_ul(table["e2dnde"], table["e2dnde_errp"]) table["e2dnde_ul"][is_ul] = e2dnde_ul[is_ul] # Square root of test statistic table["sqrt_ts"] = self.data["Sqrt_TS_Band"] return FluxPoints(table)
def flux_points_dnde(model): e_ref = [np.sqrt(10), np.sqrt(10 * 100)] * u.TeV table = Table() table.meta["SED_TYPE"] = "dnde" table["e_ref"] = e_ref table["dnde"] = model(e_ref) return FluxPoints(table)
def flux_points_e2dnde(model): e_ref = [np.sqrt(10), np.sqrt(10 * 100)] * u.TeV table = Table() table.meta["SED_TYPE"] = "e2dnde" table["e_ref"] = e_ref table["e2dnde"] = (model(e_ref) * e_ref**2).to("erg cm-2 s-1") return FluxPoints(table)
def flux_points(self): """Differential flux points (`~gammapy.spectrum.FluxPoints`).""" d = self.data table = Table() table.meta["SED_TYPE"] = "dnde" self._add_source_meta(table) valid = np.isfinite(d["sed_e_ref"].value) if valid.sum() == 0: return None table["e_ref"] = d["sed_e_ref"] table["e_min"] = d["sed_e_min"] table["e_max"] = d["sed_e_max"] table["dnde"] = d["sed_dnde"] table["dnde_err"] = d["sed_dnde_err"] table["dnde_errn"] = d["sed_dnde_errn"] table["dnde_errp"] = d["sed_dnde_errp"] table["dnde_ul"] = d["sed_dnde_ul"] # Only keep rows that actually contain information table = table[valid] # Only keep columns that actually contain information def _del_nan_col(table, colname): if np.isfinite(table[colname]).sum() == 0: del table[colname] for colname in table.colnames: _del_nan_col(table, colname) return FluxPoints(table)
def flux_points_flux(model): e_min = [1, 10] * u.TeV e_max = [10, 100] * u.TeV table = Table() table.meta["SED_TYPE"] = "flux" table["e_min"] = e_min table["e_max"] = e_max table["flux"] = model.integral(e_min, e_max) return FluxPoints(table)
def run(self, e_ref, e_min, e_max, steps="all"): """Run light curve extraction. Normalize integral and energy flux between emin and emax. Parameters ---------- e_ref : `~astropy.unit.Quantity` reference energy of dnde flux normalization e_min : `~astropy.unit.Quantity` minimum energy of integral and energy flux normalization interval e_max : `~astropy.unit.Quantity` minimum energy of integral and energy flux normalization interval steps : list of str Which steps to execute. Available options are: * "err": estimate symmetric error. * "errn-errp": estimate asymmetric errors. * "ul": estimate upper limits. * "ts": estimate ts and sqrt(ts) values. * "norm-scan": estimate likelihood profiles. By default all steps are executed. Returns ------- lightcurve : `~gammapy.time.LightCurve` the Light Curve object """ self.e_ref = e_ref self.e_min = e_min self.e_max = e_max rows = [] for dataset in self.datasets.datasets: row = { "time_min": dataset.counts.meta["t_start"].mjd, "time_max": dataset.counts.meta["t_stop"].mjd, } row.update(self.estimate_time_bin_flux(dataset, steps)) rows.append(row) meta = OrderedDict([("SED_TYPE", "likelihood")]) table = table_from_row_data(rows=rows, meta=meta) table = FluxPoints(table).to_sed_type("flux").table return LightCurve(table)
def flux_points(self): """Integral flux points (`~gammapy.spectrum.FluxPoints`).""" table = Table() table.meta["SED_TYPE"] = "flux" table["e_min"] = self._ebounds[:-1] table["e_max"] = self._ebounds[1:] table["flux"] = self._get_flux_values("Flux") flux_err = self._get_flux_values("Unc_Flux") table["flux_errn"] = np.abs(flux_err[:, 0]) table["flux_errp"] = flux_err[:, 1] # handle upper limits is_ul = np.isnan(table["flux_errn"]) table["is_ul"] = is_ul table["flux_ul"] = np.nan * flux_err.unit flux_ul = compute_flux_points_ul(table["flux"], table["flux_errp"]) table["flux_ul"][is_ul] = flux_ul[is_ul] return FluxPoints(table)
def flux_points(self): """Flux points (`~gammapy.spectrum.FluxPoints`).""" table = Table() table.meta["SED_TYPE"] = "dnde" mask = ~np.isnan(self.data["Flux_Points_Energy"]) table["e_ref"] = self.data["Flux_Points_Energy"][mask] table["e_min"] = self.data["Flux_Points_Energy_Min"][mask] table["e_max"] = self.data["Flux_Points_Energy_Max"][mask] table["dnde"] = self.data["Flux_Points_Flux"][mask] table["dnde_errn"] = self.data["Flux_Points_Flux_Err_Lo"][mask] table["dnde_errp"] = self.data["Flux_Points_Flux_Err_Hi"][mask] table["dnde_ul"] = self.data["Flux_Points_Flux_UL"][mask] table["is_ul"] = self.data["Flux_Points_Flux_Is_UL"][mask].astype( "bool") return FluxPoints(table)
def flux_points(self): """Flux points (`~gammapy.spectrum.FluxPoints`).""" table = Table() table.meta["SED_TYPE"] = "flux" table["e_min"] = self._ebounds[:-1] table["e_max"] = self._ebounds[1:] flux = self._get_flux_values("Flux") flux_err = self._get_flux_values("Unc_Flux") table["flux"] = flux table["flux_errn"] = np.abs(flux_err[:, 0]) table["flux_errp"] = flux_err[:, 1] nuFnu = self._get_flux_values("nuFnu", "erg cm-2 s-1") table["e2dnde"] = nuFnu table["e2dnde_errn"] = np.abs(nuFnu * flux_err[:, 0] / flux) table["e2dnde_errp"] = nuFnu * flux_err[:, 1] / flux is_ul = np.isnan(table["flux_errn"]) table["is_ul"] = is_ul # handle upper limits table["flux_ul"] = np.nan * flux_err.unit flux_ul = compute_flux_points_ul(table["flux"], table["flux_errp"]) table["flux_ul"][is_ul] = flux_ul[is_ul] # handle upper limits table["e2dnde_ul"] = np.nan * nuFnu.unit e2dnde_ul = compute_flux_points_ul(table["e2dnde"], table["e2dnde_errp"]) table["e2dnde_ul"][is_ul] = e2dnde_ul[is_ul] # Square root of test statistic table["sqrt_TS"] = [ self.data["Sqrt_TS" + _] for _ in self._ebounds_suffix ] return FluxPoints(table)
def run(self, e_ref, e_min, e_max, steps="all", atol="1e-6 s"): """Run light curve extraction. Normalize integral and energy flux between emin and emax. Parameters ---------- e_ref : `~astropy.units.Quantity` reference energy of dnde flux normalization e_min : `~astropy.units.Quantity` minimum energy of integral and energy flux normalization interval e_max : `~astropy.units.Quantity` minimum energy of integral and energy flux normalization interval steps : list of str Which steps to execute. Available options are: * "err": estimate symmetric error. * "errn-errp": estimate asymmetric errors. * "ul": estimate upper limits. * "ts": estimate ts and sqrt(ts) values. * "norm-scan": estimate fit statistic profiles. By default all steps are executed. atol : `~astropy.units.Quantity` Tolerance value for time comparison with different scale. Default 1e-6 sec. Returns ------- lightcurve : `~gammapy.time.LightCurve` the Light Curve object """ atol = u.Quantity(atol) self.e_ref = e_ref self.e_min = e_min self.e_max = e_max rows = [] self.group_table_info = group_datasets_in_time_interval( datasets=self.datasets, time_intervals=self.time_intervals, atol=atol) if np.all(self.group_table_info["Group_ID"] == -1): raise ValueError( "LightCurveEstimator: No datasets in time intervals") for igroup, time_interval in enumerate(self.time_intervals): index_dataset = np.where( self.group_table_info["Group_ID"] == igroup)[0] if len(index_dataset) == 0: log.debug("No Dataset for the time interval " + str(igroup)) continue row = { "time_min": time_interval[0].mjd, "time_max": time_interval[1].mjd } interval_list_dataset = Datasets( [self.datasets[int(_)].copy() for _ in index_dataset]) self._set_scale_model(interval_list_dataset) row.update( self.estimate_time_bin_flux(interval_list_dataset, time_interval, steps)) rows.append(row) table = table_from_row_data(rows=rows, meta={"SED_TYPE": "likelihood"}) table = FluxPoints(table).to_sed_type("flux").table return LightCurve(table)
# Fit norm in bands diff_flux = list() diff_flux_err = list() e_err_hi = list() e_err_lo = list() energy = list() for ii in range(len(binning) - 1): energ = np.sqrt(binning[ii] * binning[ii + 1]) energy.append(energ) e_err_hi.append(binning[ii + 1]) e_err_lo.append(binning[ii]) fit.fit_range = binning[[ii, ii + 1]] fit.run() res = fit.result[0].fit diff_flux.append(res.model(energ).to('cm-2 s-1 TeV-1')) err = res.model_with_uncertainties(energ.to('keV').value) diff_flux_err.append(err.s * u.Unit('cm-2 s-1 keV-1')) table = Table() table['e_ref'] = energy table['e_min'] = e_err_lo table['e_max'] = e_err_hi table['dnde'] = diff_flux table['dnde_err'] = diff_flux_err points = FluxPoints(table) result = SpectrumResult(fit=best_fit, points=points) result.plot_spectrum() plt.savefig('fluxpoints.png')
sed_type="dnde", model=source_fermi_3fhl.spectral_model()) # Finally we stack the flux points into a single `~gammapy.spectrum.FluxPoints` object and drop the upper limit values, because currently we can't handle them in the fit: # In[ ]: # Stack flux point tables flux_points = FluxPoints.stack( [flux_points_gammacat, flux_points_3fhl, flux_points_3fgl]) t = flux_points.table t["dnde_err"] = 0.5 * (t["dnde_errn"] + t["dnde_errp"]) # Remove upper limit points, where `dnde_errn = nan` is_ul = np.isfinite(t["dnde_err"]) flux_points = FluxPoints(t[is_ul]) flux_points # ## Power Law Fit # # First we start with fitting a simple `~gammapy.modeling.models.PowerLawSpectralModel`. # In[ ]: pwl = PowerLawSpectralModel(index=2, amplitude="1e-12 cm-2 s-1 TeV-1", reference="1 TeV") model = SkyModel(spectral_model=pwl) # After creating the model we run the fit by passing the `'flux_points'` and `'model'` objects:
1.23e-12, 8.37e-13, ]) e2dnde_err = np.array([ 0.08e-11, 0.05e-11, 0.04e-11, 0.03e-11, 0.31e-12, 0.29e-12, 0.28e-12, 0.24e-12, 2.91e-13, ]) dnde = e2dnde / e_ref**2.0 dnde_err = dnde * e2dnde_err / e2dnde table = Table() table.meta["SED_TYPE"] = "dnde" table["dnde"] = dnde table["dnde"].unit = "cm-2 s-1 TeV-1" table["dnde_err"] = dnde_err table["dnde_err"].unit = "cm-2 s-1 TeV-1" table["e_ref"] = e_ref table["e_ref"].unit = "TeV" flux_points_hawc = FluxPoints(table) filename = Path("$GAMMAPY_EXTRA/datasets/hawc_crab/HAWC19_flux_points.fits") flux_points_hawc.write(filename, overwrite=True)