def analytical_butterfly(self): """Calculate butterfly analytically Disclaimer: Only available for PowerLaw assuming no correlation Returns ------- x : float Energy array [TeV] butterfly : float Butterfly """ from gammapy.spectrum import df_over_f if self.spectral_model is not 'PowerLaw': raise NotImplementedError('Analytical butterfly calculation' 'not implemented for model {}'.format( self.spectral_model)) x_min = np.log10(self.fit_range[0].value) x_max = np.log10(self.fit_range[1].value) x = np.logspace(x_min, x_max, 1000) * self.energy_range.unit x = x.to('TeV').value e0 = self.parameters.reference.to('TeV').value f0 = self.parameters.norm.to('cm-2 s-1 TeV-1').value df0 = self.parameter_errors.norm.to('cm-2 s-1 TeV-1').value dg = self.parameter_errors.index.value cov = 0 butterfly = df_over_f(x, e0, f0, df0, dg, cov) * y return x, butterfly
def plot_fit_function(self, ax=None, butterfly=True, energy_unit='TeV', flux_unit='cm-2 s-1 TeV-1', e_power=0, **kwargs): """Plot fit function kwargs are forwarded to :func:`~matplotlib.pyplot.errorbar` Parameters ---------- ax : `~matplolib.axes`, optional Axis energy_unit : str, `~astropy.units.Unit`, optional Unit of the energy axis flux_unit : str, `~astropy.units.Unit`, optional Unit of the flux axis e_power : int Power of energy to multiply flux axis with Returns ------- ax : `~matplolib.axes`, optional Axis """ import matplotlib.pyplot as plt from gammapy.spectrum import df_over_f ax = plt.gca() if ax is None else ax func = self.to_sherpa_model() x_min = np.log10(self.energy_range[0].value) x_max = np.log10(self.energy_range[1].value) x = np.logspace(x_min, x_max, 10000) * self.energy_range.unit y = func(x.to('keV').value) * Unit('cm-2 s-1 keV-1') # Todo: Find better solution if butterfly: e = x.to('TeV').value e0 = self.parameters.reference.to('TeV').value f0 = self.parameters.norm.to('cm-2 s-1 TeV-1').value df0 = self.parameter_errors.norm.to('cm-2 s-1 TeV-1').value dg = self.parameter_errors.index.value cov = 0 e = df_over_f(e, e0, f0, df0, dg, cov) * y else: e = np.zeros(shape=x.shape()) * Unit(flux_unit) x = x.to(energy_unit).value y = y.to(flux_unit).value e = e.to(flux_unit).value y, e = np.asarray([y, e]) * np.power(x, e_power) flux_unit = Unit(flux_unit) * np.power(Unit(energy_unit), e_power) ax.errorbar(x, y, yerr=e, **kwargs) ax.set_xlabel('Energy [{}]'.format(energy_unit)) ax.set_ylabel('Flux [{}]'.format(flux_unit)) return ax
def _eval_butterfly_analytical(self, x): """Evaluate butterfly using hard-coded formulas""" if self.spectral_model == 'PowerLaw': from gammapy.spectrum import df_over_f f = self.evaluate(x) x = x.to('TeV').value e0 = self.parameters.reference.to('TeV').value f0 = self.parameters.norm.to('cm-2 s-1 TeV-1').value df0 = self.parameter_errors.norm.to('cm-2 s-1 TeV-1').value dg = self.parameter_errors.index.value # TODO: Fix this! cov = 0 df_over_f = df_over_f(x, e0, f0, df0, dg, cov) val = df_over_f * f # Errors are symmetric return (val, val) else: raise NotImplementedError('Analytical butterfly calculation' ' not implemented for model {}'.format( self.spectral_model))